web开发tips

  • 要想覆盖bootstrap样式,style要在导入bootstrap后面

  • bootstrap的container最大值就是1300多px,所以想宽一点就要覆盖/用别的

  • 1. 格式化日期

<td>{{ case.create_date|date:"Y-m-d" }}</td> 

  • 为什么案件列表的类型和状态只显示1不显示具体内容

问题是您的 Case 模型的 type 和 status 字段被定义为 CharFields,但您使用的是 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 模式,用于避免表单重复提交的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值