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")

 


  

 

        

    

posted @ 2019-01-14 23:03  漏斗倒过来  阅读(677)  评论(0编辑  收藏  举报