• Django之Form表单


    1:什么是表单

    2:HTML表单与Django表单

    3:Django中表单的使用流程

    4:常用的字段与验证器

    5:自定义验证器

    6:  提取错误信息

    7:ModelForm:

      (1)自定义错误消息

      (2)save()方法

    1什么是表单:表单是用来收集用户信息的表的集合,比如用户在网站上登入(输入自己的用户名,密码提交到网站)这个过程用到的表就是表单

    2HTML表单与django表单
      html表单:form标签,提交地址,请求方式,提交按钮

    <form action="" method="post" enctype="multipart/form-data">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="file">
        <input type="checkbox">
        <input type="submit">
    </form>

      django表单:是由Form类实现的,主要分为forms.Form和forms.ModelForm两种,前者为基本的表单或者为结合模型生成的表单

      django表单的作用:(1)类似于html页面一样生成表单模板(2)对表单提交上来的数据进行验证(重点)

    3:django表单使用的基本流程:

      (1)生成一个表单模板:

      在APP中创建一个py文件,名字为forms;这里面写表单的内容:目录如下

      forms.py代码:

    from django import forms
    
    class IndexForm(forms.Form):
        title = forms.CharField(max_length=12,label="标题")  //max_length表示最大长度,label表示标题名字
        content = forms.CharField(widget= forms.Textarea,label="内容") //widget表示表单的属性
        replay = forms.BooleanField(required=False,label="记住我")

      view.py代码:

    from django.shortcuts import render
    from django.views.generic import View
    from .forms import IndexForm
    class IndexView(View):
        def get(self,request):    //get请求的时候,返回一个IndexForm
            form = IndexForm()
            return render(request,"index.html",context={"form":form})

      html代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post">
        <table>
            {{ form.as_table  }}    //在HTML中渲染一个表单三种方式(form.as_table,form.as_ul,form.as_p),之后还要添加提交按钮
            <tr>
                <td></td>
                <td><input type="submit"></td>
            </tr>
        </table>
    </form>
    </body>
    </html>

       (2)对表单提交上来的数据进行验证

      forms.py

    from django import forms
    
    class IndexFrom(forms.Form):
        title = forms.CharField(max_length=12,label="标题",min_length=4)  //最少不能小于4个
        content = forms.CharField(widget= forms.Textarea,label="内容")
        email = forms.EmailField()    //添加一个邮箱的验证
        replay = forms.BooleanField(required=False,label="记住我")  //required=False  表示值可以不填,默认为True

      view.py

    from django.shortcuts import render,HttpResponse
    from django.views.generic import View
    from .forms import IndexFrom
    class IndexView(View):
        def get(self,request):
            form = IndexFrom()
            return render(request,"index.html",context={"form":form})
    
        def post(self,request):
            form = IndexFrom(request.POST)   //将request.POST接收到的值传给IndexForm表单进行验证,
            if form.is_valid():   //如果验证成功则为True
                return HttpResponse("ok")
            else:
                print(form.errors.get_json_data())
                return HttpResponse("fail")

    4:常用的验证器

      (1)常用的字段(Field):

        CharField:  用来接收文本

          max_length:表示最大长度

          min_length:表示最小长度

          required:表示是否必须填写,默认为True(必须)

          error_messages:验证失败给出的错误信息

        EmailField:用来验证邮箱

          错误信息的key:required,invalid

        FloatField:用来接收浮点类型,通过验证后会将值转换为浮点型

          max_value:最大值

          min_value:最小值

          错误信息的key:required,invalid,max_value,min_value

        IntegerField:用来接收整型,通过验证后会将值转换为整型

          max_value:最大值

          min_value:最小值

          错误信息的key:required,invalid,max_value,min_value

       URLField:用来接收url格式的字符串

          错误信息的key:required,invalid

      (2)常用的验证器(validator):在验证某个字段的时候可以传递一个验证器对数据进一步验证

        MaxValueValidator:验证最大值

        MinValueValidator:验证最小值

        MaxLengthValidator:验证最大长度

        MinLengthValidator:验证最小长度

        EmailValidator:验证是否是邮箱格式

        URLValidator:验证是否是URL格式

        RegexValidator:正则验证

    from django import forms
    from django.core import validators  //导入验证器
    class IndexFrom(forms.Form):
        telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]d{9}",message="请输入正确的手机号")])  //验证手机号

      5自定义验证器

      (1)如果要对一个字段进行验证不是一个长度,也不是一个最大值,正则或者也表达不清楚,还需要一些更复杂的逻辑,那么我们可以对这个字段进行自定义验证;比如注册的时候我们要判断数据库中有没有这个手机号,有的话就不能再注册了,这是我们就要在数据库中判断才知道,那么就要定义一个方法;这个方法有一个规则就是clean_fieldname(比如:clean_telephone,clean_username等,是个是固定的),比如我们要对手机号进行验证:

    from django import forms
    from django.core import validators
    from .models import User
    class IndexFrom(forms.Form):
        title = forms.CharField(max_length=12,label="标题",min_length=4)
        content = forms.CharField(widget= forms.Textarea,label="内容")
        email = forms.EmailField()
        replay = forms.BooleanField(required=False,label="记住我")
        telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]d{9}",message="请输入正确的手机号")])
    
        def clean_telephone(self):      //对手机号进行验证方式(clean_telephone)
            telephone = self.cleaned_data.get("telephone")    //拿到这个手机号
            exists = User.objects.filter(telephone=telephone).exists()   //在数据库中判断是否存在
            if exists:
                raise forms.ValidationError("手机号已经存在")
            else:
                return telephone

      (2)以上是对单个字段进行验证,如果是对多个字段进行验证的话就可以重写clean方法; 比如注册的时候要判断两次输入的密码是否一致:

    from django import forms
    from django.core import validators
    from .models import User
    class IndexFrom(forms.Form):
        title = forms.CharField(max_length=12,label="标题",min_length=4)
        content = forms.CharField(widget= forms.Textarea,label="内容")
        email = forms.EmailField()
        password = forms.CharField(max_length=18,min_length=6)
        re_password = forms.CharField(max_length=18,min_length=6)
        replay = forms.BooleanField(required=False,label="记住我")
        telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]d{9}",message="请输入正确的手机号")])
    
        def clean(self):    //重写clean方法
            cleaned_data = super().clean()   //调用父的clean()
            password = cleaned_data.get("password")
            re_password = cleaned_data.get("re_password")
            if password != re_password:
                raise forms.ValidationError("两次密码不一致")
            return cleaned_data

      6提取错误信息

      如果验证失败了,会有一些错误提示信息,如:

      form.errors:这个属性的错误信息是包含了一些html标签的错误信息

      form.errors.get_json_data():这个方法获取到的是一个字典类型的错误信息,将某个字段的名字作为key,错误信息为值得字典

      form.as_json():这个方法是将form.get_json_data()返回的字典dump成json格式的字符串。

      以上方法获取的都是比较复杂的数据比如:
      

    {'email': [{'message': 'Enter a valid email address.', 'code': 'invalid'}], '__all__': [{'message': '两次密码不一致', 'code': ''}]}

      如果我们想把错误信息放到一个列表而不是字典中,我们可以自己定义一个方法,对错误信息重新整理:

        def get_errors(self):
            errors = self.errors.get_json_data()
            new_errors = {}
            for key,message_dicts in errors.items():   //对字典进行遍历
                messages = []
                for message in message_dicts:   //
                    messages.append(message["message"])
                new_errors[key] = messages
            return new_errors

      7ModelForm:

      (1)我们在写表单的时候发现表单中的Field和模型中的Field基本上一样,而且表单中需要验证的数据就是我们要保存到数据库中的数据,那么我们就可以将两者绑定。比如我们有个模型(User):

    from django.db import models
    
    class User(models.Model):
        username = models.CharField(max_length=12)
        telephone = models.CharField(max_length=11)
        password = models.CharField(max_length=18)
        email = models.EmailField()
    
        class Meta:
            db_table = "user"

      那么我们再写表单的时候可以这样写:

    class UserForm(forms.ModelForm):   //继承自ModelForm
        class Meta:    //定义Meta类
            model = User   //规定继承自那个模型
            fields = "__all__"  //规定继承那些字段(继承所有字段)
            # fields = ["username","telephone"]    //继承username,telephone两个字段
            # exclude = ["username"]  //除了username字段其他都继承
            error_messages={           //定义一个错误提示信息
                "username":{"max_length":"最多不能超过10个字符","min_length":"最少不能少于3个字符"},
                "telephone":{"required":"必须传入手机号"}
            }

      (2)save()方法:这个方法是把数据直接保存到数据库中(必须保证clean方法没有问题之后才能使用,不然会报错),我们还可以传入一个参数commit=False;表示只会生成一个对象不会真正的保存到数据库中。

     def post(self,request):
            form = IndexFrom(request.POST)
            if form.is_valid():
                # form.save()      //直接保存到数据库中
                user = form.save(commit=False)  //生成一个user对象
                user.password = "123123"  //给对象添加一个密码
                user.save()  //保存到数据库中
                
                return HttpResponse("ok")


      

            

        

  • 相关阅读:
    纪念又一次ak
    hdu5618
    bzoj3393
    bzoj3438
    [JSOI2007]建筑抢修
    [CQOI2014]数三角形
    [BZOJ2662][BeiJing wc2012]冻结
    [NOIP2015]运输计划
    [ZJOI2006]超级麻将
    [APIO2009]抢掠计划
  • 原文地址:https://www.cnblogs.com/yan-peng/p/10269596.html
Copyright © 2020-2023  润新知