-
要想覆盖bootstrap样式,style要在导入bootstrap后面
-
bootstrap的container最大值就是1300多px,所以想宽一点就要覆盖/用别的
-
1. 格式化日期
<td>{{ case.create_date|date:"Y-m-d" }}</td>
-
为什么案件列表的类型和状态只显示1不显示具体内容
问题是您的 Case
模型的 type
和 status
字段被定义为 CharField
s,但您使用的是 choices。Django 的 CharField
将存储在 choices 元组中提供的字符串值,而不是人类可读的描述。当 get_type_display()
和 get_status_display()
正常工作时,它们正在访问原始存储值 (1, 2, 3)。要解决这个问题,你需要将这些字段更改为 IntegerField
或 SmallIntegerField
,然后 Django 的模板系统将正确使用显示值。
引入格式
<img src="{% static 'img/1.jpg' %}" alt="律所logo" height="30" class="d-inline-block align-top">w
<link rel="stylesheet" href="{% static 'plugins/bootstrap-5.3.0-alpha1-dist/css/bootstrap.css' %}">
<script src="{% static 'echarts.min.js' %}"></script>
外键会出现字段xx_id
media的配置(上传文件):
media用户上传的数据目录
1.配置media
编辑myproject/myproject/urls.py
from django.urls import path, re_path
from django.conf import settings
from django.views.static import serve
urlpatterns = [
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
编辑myproject/myproject/settings.py(写哪都可以,别写人家函数里面就行)
import os
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = '/media/'
新建目录 [项目名]/media media在根目录下,和app同一级
2.数据库:
ImageField / FileField
语法一样,一个是图片格式,一个是文件
upload_to后面跟文件存储的地址,会自动在media目录下新建你所写的文件夹名,并把东西放进去,并保存到数据库
materials = models.FileField(upload_to='case_materials/', null=True, blank=True, verbose_name="案件材料")
3.视图
接下来实现图片的上传(保存至本地与数据库)
可以直接放到之前的新建/更新里面
注意:新增file位置给form:files=request.FILES
form = LawyerCaseModelForm(data=request.POST, instance=row_object,files=request.FILES)
def lawyer_edit(request, nid):
"""更新案件"""
# 判断nid指向的id是否存在
# 能获取到就是对象,获取不到就是none
row_object = models.Case.objects.filter(id=nid).first()
if not row_object:
# 若获取不到,这里可以自定义一个错误页面/返回列表
return redirect('/lawyer/workList/')
title = "更新案件进度"
if request.method == "GET":
form = LawyerCaseModelForm(instance=row_object)
return render(request, 'change.html', {"title": title, 'form': form})
# post提交时,要获取nid才能知道它要更新哪个
# 这里加个instance=row_object就告诉它不要新增数据啦,是更新数据
form = LawyerCaseModelForm(data=request.POST, instance=row_object,files=request.FILES)
if form.is_valid():
# 对于文件会自动保存
# 目录信息会自动保存至数据库中
form.save()
return redirect('/lawyer/workList/')
render(request, 'change.html', {"title": title, 'form': form})
4.html模板中的表单配置:
(1)form
确保你的模板中正确配置了表单,特别是文件字段:
特别注意enctype="multipart/form-data"
,这是文件上传所必需的
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-primary">提交</button>
</form>
(2)json☆
btn是绑定了所有用按钮 样式的 btnAddSave表单保存id formAddSave是表单id
var formData = new FormData($("#formAddSave")[0]);
data: formData, processData: false, // 必须设置为 false contentType: false, // 必须设置为 false
<script type="text/javascript">
$(function () {
{#点击按钮时清空之前的错误信息#}
btn();
{#保存按钮绑定事件#}
bindBtnSaveEvent();
})
function btn() {
$("#btn").click(function () {
// 清除错误信息
$(".error_msg").empty();
})
}
function bindBtnSaveEvent() {
$("#btnAddSave").click(function () {
// 清除错误信息
$(".error_msg").empty();
var formData = new FormData($("#formAddSave")[0]);
$.ajax({
url: "/lawyer/caseAdd/",
type: "post",
data: formData,
processData: false, // 必须设置为 false
contentType: false, // 必须设置为 false
success: function (res) {
if (res.status) {
alert("新增案件成功");
// 清除表单 $("#formAddSave")是jqury对象 $("#formAddSave")[0]是dom对象
$("#formAddSave")[0].reset();
//关闭模态框
$("#staticBackdrop").modal('hide');
//刷新页面
location.reload();
} else {
$.each(res.error, function (name, errorList) {
$("#id_" + name).next().text(errorList[0]);
})
}
}
})
});
}
</script>
5.查看文件
图片
(有的没图片的话要分类说明没图片怎么样,要不会报错)(详见下面文件部分)
<img src="/media/{{ obj.img }}" style="height: 60px;">
{% for obj in page_queryset %}
<tr>
<th>{{ obj.id }}</th>
<td>
<img src="/media/{{ obj.img }}" style="height: 60px;">
</td>
<td>{{ obj.name }}</td>
<td>{{ obj.count }}</td>
</tr>
{% endfor %}
</tbody>
文件
记得不是都有文件的话要分类
{% if case.materials %}
<td><a href="{{ case.materials.url }}"></a> {{ case.materials }}</td>
{% else %}
<td>暂无文件</td>
{% endif %}
{% for case in queryset %}
<tr>
<td>{{ case.case_id }}</td>
<td>{{ case.name }}</td>
<td>{{ case.create_date|date:"Y-m-d" }}</td>
<td>{{ case.get_type_display }}</td>
{% if case.materials %}
<td><a href="{{ case.materials.url }}"></a> {{ case.materials }}</td>
{% else %}
<td>暂无文件</td>
{% endif %}
<td>{{ case.get_status_display }}</td>
<td>{{ case.verdict }}</td>
<td>{{ case.get_party_display }}</td>
<td>
<a class="btn btn-primary btn-sm" href="/lawyer/{{ case.id }}/edit/">更新</a>
{# <a class="btn btn-danger btn-sm" href="/lawyer/{{ case.id }}/delete/">删除</a>#}
</td>
</tr>
{% endfor %}
浏览器报错显示重定向过多、点击链接不跳转、调用不出来数据库文件/外部api
首先检查中间件 其次是urls和视图和html
一般是要用的文件夹没注明不需要登陆验证(例如从其他网站获取的数据天气和media文件
还有就是路径的问题 各种绝对路径相对路径 修改路径后可能有的没改
给个范例 登录注销 law/templates/account/login.html
中间件
# 不需要登录验证的URL列表
allowed_paths = [
'/home/', # 欢迎主页
'/account/', # 登录页
'/static/',
'/media/',
'/admin/', # admin页面
'/weather/', # 天气API!!
]
# 验证用户是否登录
info_dict = request.session.get('info')
if not info_dict:
return redirect('/account/login/')
urls
path('account/login/', account.account_login, name='login'),
path('account/logout/', account.account_logout, name='logout'),
account.py (这里主要问题出在最后render和重定向的路径那里
"""账户登录"""
from django.shortcuts import render, redirect
from django import forms
from law import models
from django.conf import settings
class LoginForm(forms.Form):
name = forms.CharField(
label="用户名",
widget=forms.TextInput(attrs={"class": "form-control"}),
required=True
)
password = forms.CharField(
label="密码",
widget=forms.PasswordInput(attrs={"class": "form-control"}),
required=True
)
def account_login(request):
"""登录"""
if request.method == "GET":
form = LoginForm()
return render(request, "account/login.html", {'form': form})
form = LoginForm(data=request.POST)
if form.is_valid():
username = form.cleaned_data['name']
password = form.cleaned_data['password']
# 检查管理员
admin = models.Admin.objects.filter(name=username, password=password).first()
if admin:
request.session["info"] = {
'id': admin.id,
'name': admin.name,
'type': 'admin',
'photo': '/static/img/default_avatar.jpg' # 管理员使用默认头像
}
return redirect('/manager/home/')
# 检查律师
lawyer = models.Lawyer.objects.filter(name=username, password=password).first()
if lawyer:
# 打印调试信息
print("Lawyer photo:", lawyer.photo.url if lawyer.photo else "No photo")
request.session["info"] = {
'id': lawyer.id,
'name': lawyer.name,
'type': 'lawyer',
'photo': lawyer.photo.url if lawyer.photo else '/static/img/default_avatar.jpg' # 直接使用url属性
}
return redirect('/lawyer/home/')
# 检查当事人
party = models.Party.objects.filter(name=username, password=password).first()
if party:
request.session["info"] = {
'id': party.id,
'name': party.name,
'type': 'party',
'photo': party.photo.url if party.photo else '/static/img/default_avatar.jpg' # 直接使用url属性
}
return redirect('/party/home/')
form.add_error("password", "用户名或密码错误")
return render(request, "account/login.html", {'form': form})
def account_logout(request):
"""注销退出登录"""
request.session.clear()
return redirect("/account/login/")
注销链接
<li><a class="dropdown-item" href="/account/logout/">注销</a></li>
每次一刷新就会自动创建一条和之前一样的留言!!
这是因为表单提交后需要重定向,避免刷新时重复提交,修改 home.py 中的视图函数
主要修改是在成功创建留言后添加了重定向:
return redirect(f'/home/{lawyer_id}/lawyerFeedback/')
这样当用户提交留言后会重定向到同一个页面,而不是停留在 POST 请求的页面。这样刷新页面时就不会重复提交表单了。
这是一个常见的 POST-Redirect-GET 模式,用于避免表单重复提交的问题。