• Day 62 django form modelform组件


    Day 62 django form modelform组件

    1、批量操作数据

    浏览器访问一个django路由 立刻创建10万条数据并展示到前端页面

    create()all()
    
    • 1

    涉及到大批量数据的创建 直接使用create可能会造成数据库崩溃
    批量数据创建>>>:bulk_create()
    批量数据修改>>>:bulk_update()

    def index(request):;
        for i inrange(100000):
            models.Book.objects.create(title=f'第{i}本书')
        book_list = []
        for i inrange(100000):
            book_obj = models.Book(title=f'第{i}本书')
            book_list.append(book_obj)
        models.Book.objects.bulk_create(book_list)  # 批量创建数据
        book_query = models.Book.objects.all()
        return render(request,'booklist.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    当数据比较大的时候 数据应该考虑分页
    通过divmod() 获取总数居和分页展示的数据得出的总页码

    前端模板语法不支持rang 但是后端支持 我们可以在后端创建好html标签 然后传递给html页面使用

    2、自定义分页器

    def booklist(request):
        from app01.plugins import mypage
        book_query = models.Book.objects.all()
        page_obj = mypage.Pagination(current_page=request.GET.get('page'),
                                     all_count=book_query.count())
        page_query = book_query[page_obj.start:page_obj.end]
        return render(request,'book.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    <div class="container">
        <div class="row">
        <div class="col-md-8 col-md-offset-2">
            {% for book_obj in page_query %}
        <p class="text-center">{{book_obj.title }}</p>
    {% endfor %}
        <p>{{ page_obj.page_html|safe }}</p>
        </div>
        </div>
    </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、form组件

    前戏:编写用户登录功能并且校验数据返回提示信息(form表单)

    def reg(request):
        data_dict={'name':'','pwd':''}
        if request.method=='POST':
            name=request.POST.get('name')
            pwd = request.POST.get('pwd')
            if name =='kk':
                data_dict['name']='kk已存在'
            if pwd =='123':
                data_dict['pwd']='密码太简单了'
        return render(request,'reg.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    form组件

    1. 数据校验
      支持提前设置各种校验规则 之后自动校验
    2. 渲染页面
      支持直接渲染获取用户数据的各种标签
    3. 展示信息
      支持针对不同的校验失败展示不同的提示

    form类型创建

    from django import forms
    
    class Myreg(forms.Form):
        name = forms.CharField(max_length=8,min_length=3)
        pwd = forms.CharField(min_length=3)
        age = forms.CharField(max_length=150,min_length=0)
        email = forms.EmailField()  #邮箱必须符合邮箱格式(至少有@符号)
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.1、数据校验功能

    1. 传递待校验的数据

      form_obj = views.Myreg({'name':'kk','pwd':'123','age':21,'email':5555})
      
      • 1
    2. 判断所有数据 是否符合校验

      form_obj.is_valid()
      
      • 1
    3. 获取符合校验规则的数据

      form_obj.cleaned_data
      {'pwd': '123', 'age': '21'}
      
      • 1
      • 2
    4. 查阅不符合校验规则的数据及错误原因

      form_obj.errors
      {'name': ['Ensure this value has at least 3 characters (it has 2).'], 'email': ['Enter a valid email address.']}
      
      • 1
      • 2

    form类中编写的字段默认都是必填的 少传则肯定通不过校验 is_valid
    校验如果多传了一些字段 则不参与校验 全程忽略

    3.2、渲染标签功能

    django 模板语法注释

    <# 注释 #>
    
    • 1

    方式一:(封装成都高 扩展性差)

    {{ form_obj.as_p }}  # 渲染成三个 p标签下
    {{ form_obj.as_table }}  # 直接渲染成leable
    {{ form_obj.as_ul }}  # 以无序列表形式
    
    • 1
    • 2
    • 3

    方式二:(封装成都低 扩展性好 编写困难)

    {{ form_obj.name.lable }}  # 只拿字段名
    {{ form_obj.name }}  # 输入框
    {{ form_obj.age.lable }}
    {{ form_obj.age }}
    {{ form_obj.email.lable }}
    {{ form_obj.email }}
    
    可以通过改 类中 字段 添加 lable关键字参数值 来修改 字段名
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式三(推荐使用)

    # 也可以通过 类中lable添加参数修改字段名 
    {% for foo in form_obj %}
            <p>{{ foo.label }}{{ foo }}</p>
    {% endfor %}
    
    • 1
    • 2
    • 3
    • 4

    3.3、展示提示信息

    form组件 自带校验规则
    创建form类 通过函数将form类 传至前端 前端自动会校验

    form表单如何取消浏览器自动添加的数据校验功能
    novalidate

    #前端
    <form action="/app01/func/" method="post" novalidate>  # 在form中填写 novalidate
    
        {% for foo in form_obj %}
            <p>{{ foo.label }}{{ foo }}</p>
        {% endfor %}
        <input type="submit" name="提交">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    #后端
    def func(request):
        form_obj=Myreg()
        if request.method=='POST':
    
            form_obj=Myreg(request.POST)
            if form_obj.is_valid():
                print(form_obj.cleaned_data)
            else:print(form_obj.errors)
        return render(request,'form_reg.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    错误提示底层原理

    def func(request):
        form_obj=Myreg()
        if request.method=='POST':
    
            form_obj=Myreg(request.POST)
            if form_obj.is_valid():
                print(form_obj.cleaned_data)
            else:print(form_obj.errors)  # form_obj.errors 获取到错误信息 传给后端
        return render(request,'form_reg.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    <form action="/app01/func/" method="post" novalidate>
    {#    {{ form_obj.as_p }}#}
    
        {% for foo in form_obj %}
            <p>{{ foo.label }}{{ foo }}
                <spen style="color: red;">{{ foo.errors.0 }}</spen>  #这里 将 form的每一条对应的错误 取其 错误 文本信息展示
            </p>
        {% endfor %}
        <input type="submit" name="提交">
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    数据校验正确的话 直接将正确的数据字典 直接传至数据库

    def func(request):
        form_obj=Myreg()
        if request.method=='POST':
    
            form_obj=Myreg(request.POST)
            if form_obj.is_valid():
                data_dict=form_obj.cleaned_data
                models.User.objects.create(**data_dict)  # 直接传至数据库
            else:print(form_obj.errors)
        return render(request,'form_reg.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.4、重要字段参数

    参数功能
    max_length/min_length字符最大长度值和最小值
    max_value/min_value数字 最大长度值 和最小值
    label字段注释(修改字段名)
    error_messages错误提示
    required是否为空
    widget标签类型、标签属性
    inital默认值
    validators正则校验(需要倒模块)

    4、钩子函数

    提供自定义的校验方式

    4.1、局部钩子

    校验单个字段

    class Myreg(forms.Form):
        name = forms.CharField(max_length=8,min_length=3,label='用户名')
        pwd = forms.CharField(min_length=3,label='密码')
        pwd_again=forms.CharField(min_length=3,label='确认密码')
        age = forms.IntegerField(max_value=150,min_value=0,label='年龄')
        email = forms.EmailField()  #邮箱必须符合邮箱格式(至少有@符号)
    
        #校验用户名是否一致  局部钩子
        def clean_name(self):
            name = self.cleaned_data.get('name')
            res = models.User.objects.filter(name=name).first()
            if res:
                return self.add_error('name','用户名已存在')
            return name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4.2、全局钩子

    校验两次密码是否一致

    class Myreg(forms.Form):
        name = forms.CharField(max_length=8,min_length=3,label='用户名')
        pwd = forms.CharField(min_length=3,label='密码')
        pwd_again=forms.CharField(min_length=3,label='确认密码')
        age = forms.IntegerField(max_value=150,min_value=0,label='年龄')
        email = forms.EmailField()  #邮箱必须符合邮箱格式(至少有@符号)
        
        #2 校验两次密码是否一致
        def clean(self):
            pwd =self.cleaned_data.get('name')
            pwd_again=self.cleaned_data.get('pwd_again')
            if not pwd==pwd_again:
                return self.add_error('pwd_again','两次密码不一致')
            return self.cleaned_data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5、modelform组件

    modelform是form的优化版本 使用更简单 功能更强大

    class MymodelForm(forms.ModelForm):
        class Meta:
            model = models.User
            fields = '__all__'
            labels={   #填写字段被指
                'name': '用户名',
            }
    
    
    def func1(request):
        md_obj=MymodelForm()
        if request.method == 'POST':
            #如果要修改字段的话 需要将修改的字段 查找出来 然后传给 modelform 对象
           # edit_obj = models.User.objects.filter(name='ming').first()
            md_obj = MymodelForm(request.POST) #修改字段的参数 instance=edit_obj
            if md_obj.is_valid():
                md_obj.save()
        return render(request,'md_reg.html',locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    关于app爬虫的环境准备
    数据库查询层级结构
    flask框架-[实现websocket]:将socketio处理函数部分集中管理,使用类的方式来管理,集中管理socketio处理函数
    HashData的湖仓一体思考:Iceberg、Hudi特性讲解与支持方案
    Java 基础 --- Java变量储存机制及参数传递
    git 实际使用命令
    【全网最全】2022最新版前端 -- 面试题
    Jmeter基础(3) 发起一次请求
    快上车,LLM专列:想要的资源统统给你准备好了
    【资损】分布式系统并发互斥设计
  • 原文地址:https://blog.csdn.net/weixin_71967396/article/details/126773384