精华内容
下载资源
问答
  • Django 表单

    2021-01-03 02:09:33
    Django 表单 HTML表单是网站交互性的经典方式。 本章将介绍如何用Django对用户提交的表单数据进行处理。 HTTP 请求 HTTP协议以”请求-回复”的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析...
  • django 表单

    2020-07-12 23:18:48
    django 表单django 表单django表单的作用验证数据基本用法常用的FieldCharField:EmailField:FloatField:IntegerField:URLField:常用验证器 django 表单 django表单的作用 在Django中的表单,主要有两个功能: ...

    django 表单

    django表单的作用

    在Django中的表单,主要有两个功能:

    1. 渲染表单模板(只有前后端不分离时才有可能使用,一般情况不用)。
    2. 表单验证数据是否合法。

    验证数据基本用法

    1. app/forms.py中定义表单验证类,根据前台提交的每个字段定义对应的属性进行验证。
    2. 实例化表单验证类(传入前台提交的参数)。
    3. 通过form.is_valid()校验提交的参数。
    4. 如果校验成功,则从form.cleaned_data中获取前台提交的参数。
    5. 如果校验失败,则从form.errors中获取错误信息,form.errors获取的html格式的错误信息,可以通过form.errors.get_json_data()获取字典格式的错误信息。
      在这里插入图片描述
      自定义错误信息
      通过Field的error_messages属性定义每个校验的错误信息。如下:
      在这里插入图片描述

    常用的Field

    CharField:

    用来接收文本。
    参数:
    max_length:这个字段值的最大长度。
    min_length:这个字段值的最小长度。
    required:这个字段是否是必须的。默认是必须的。
    error_messages:在某个条件验证失败的时候,给出错误信息。

    EmailField:

    用来接收邮件,会自动验证邮件是否合法。
    错误信息的key:required、invalid。

    FloatField:

    用来接收浮点类型,并且如果验证通过后,会将这个字段的值转换为浮点类型。
    参数:
    max_value:最大的值。
    min_value:最小的值。
    required:这个字段是否是必须的。默认是必须的。
    错误信息的key:required、invalid、max_value、min_value。

    IntegerField:

    用来接收整形,并且验证通过后,会将这个字段的值转换为整形。
    参数:
    max_value:最大的值。
    min_value:最小的值。
    错误信息的key:required、invalid、max_value、min_value。

    URLField:

    用来接收url格式的字符串。
    错误信息的key:required、invalid。

    常用验证器

    在验证某个字段的时候,可以传递一个validators参数用来指定验证器,进一步对数据进行过滤。
    很多验证器其实通过Field或者一些参数就可以指定。比如EmailValidator,可以通过EmailField来指定,比如MaxValueValidator,可以通过max_value参数来指定。

    1. MaxValueValidator:验证最大值。
    2. MinValueValidator:验证最小值。
    3. MinLengthValidator:验证最小长度。
    4. MaxLengthValidator:验证最大长度。
    5. EmailValidator:验证是否是邮箱格式。
    6. URLValidator:验证是否是URL格式。
    7. RegexValidator:如果还需要更加复杂的验证,那么可以通过正则表达式的验证器:RegexValidator。

    如下: 验证手机号码的正则表达式验证器。
    在这里插入图片描述

    自定义验证字段的方法

    在注册的表单验证中,我们想要验证手机号码是否已经被注册过了,那么这时候就需要在数据库中进行判断才知道。
    对某个字段进行自定义的验证方式是,定义一个方法,这个方法的名字定义规则是:clean_fieldname。如果验证失败,那么就抛出一个验证错误。

    校验单个属性

    如下:定义clean_属性名的方法针对单个属性进行校验
    在这里插入图片描述

    校验多个属性

    如下: 重写父类的clean方法。
    在这里插入图片描述

    提取错误信息

    django原生的错误信息展示比较混乱,需要提取其中需要的信息返回给前端。
    在表单类中定义get_error_msg方法(可以定义一个父类,将get_error_msg写在父类中,所有的表单类都继承这个父类)

    def get_error_msg(self):
    	errors = self.errors.get_json_data()
        err_msg = {}
        for key, msg_list in errors.items():
            item_msg = []
            for msg in msg_list:
                item_msg.append(msg["message"])
            err_msg[key] = item_msg
        return err_msg
    

    在这里插入图片描述

    ModelForm

    如果一个表单中的字段和最终要保存到数据库的字段基本一致,可以考虑使用ModelForm。
    如下:
    模型Article

    from django.db import models
    from django.core import validators
    class Article(models.Model):
        title = models.CharField(max_length=10,validators=[validators.MinLengthValidator(limit_value=3)])
        content = models.TextField()
        author = models.CharField(max_length=100)
        category = models.CharField(max_length=100)
        create_time = models.DateTimeField(auto_now_add=True)
    

    在写表单的时候,就不需要把Article模型中所有的字段都一个个重复写一遍。

    from django import forms
    class ArticleForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = "__all__"
    

    ArticleForm继承自forms.ModelForm。
    定义Meta类,在Meta类中指定了model=Article,以及fields=“all”,这样就可以将Article模型中所有的字段都复制过来,进行验证。

    验证指定字段

    如果只想针对其中几个字段进行验证,那么可以给fields指定一个列表,将需要的字段写进去。比如只想验证title和content,那么可以使用以下代码实现:

    from django import forms
    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = ['title','content']
    

    如果要验证的字段比较多,只是除了少数几个字段不需要验证,那么可以使用exclude来代替fields。比如我不想验证category,那么示例代码如下:

    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            exclude = ['category']
    

    如果需要针对字段进行更复杂的验证,那么根使用普通Form是一样的,在Form中定义clean_字段名的校验方法,或者多个字段的联合校验可以重写clean方法。

    自定义错误消息

    使用ModelForm,因为字段都不是在表单中定义的,而是在模型中定义的,因此一些错误消息无法在字段中定义。
    那么这时候可以在Meta类中,定义error_messages,然后把相应的错误消息写到里面去。

    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            exclude = ['category']
            error_messages = {
                'title':{
                    'max_length': '最多不能超过10个字符!',
                    'min_length': '最少不能少于3个字符!'
                },
                'content': {
                    'required': '必须输入content!',
                }
            }
    

    save方法

    ModelForm的save方法,可以在验证完成后直接调用save方法,就可以将这个数据保存到数据库中了,不需要再从cleaned_data中取出每一个字段再去实例化模型对象,调用模型对象的save方法。

    form = MyForm(request.POST)
    if form.is_valid():
        form.save()
        return HttpResponse('succes')
    else:
        print(form.get_errors())
        return HttpResponse('fail')
    

    在调用save方法的时候,如果传入一个commit=False,那么只会生成这个模型的对象,而不会把这个对象真正的插入到数据库中。比如表单上验证的字段没有包含模型中所有的字段,这时候就可以先创建对象,再根据填充其他字段,把所有字段的值都补充完成后,再保存到数据库中。

    form = MyForm(request.POST)
    if form.is_valid():
        article = form.save(commit=False)
        article.category = 'Python'
        article.save()
        return HttpResponse('succes')
    else:
        print(form.get_errors())
        return HttpResponse('fail')
    
    展开全文
  • Django表单

    2020-06-19 13:39:44
    表单 ...只要把input标签放在form标签中,然后再添加一个提交按钮,那么以后点击提交按钮,就可以将input标签中对应的值提交给服务器了。 django中的表单 ...在Django中的表单,主要做...在讲解Django表单的具体每部分的细

    表单

    HTML中的表单

    单纯从前端的html来说,表单是用来提交数据给服务器的,不管后台的服务器用的是Django还是PHP语言还是其他语言。只要把input标签放在form标签中,然后再添加一个提交按钮,那么以后点击提交按钮,就可以将input标签中对应的值提交给服务器了。

    django中的表单

    Django中的表单丰富了传统的HTML语言中的表单。在Django中的表单,主要做以下两件事:

    1. 渲染表单模板。
    2. 表单验证数据是否合法。

    Django中使用表单的流程

    1. 在讲解Django表单的具体每部分的细节之前。我们首先先来看下整体的使用流程。这里以一个做一个留言板为例。首先我们在后台服务器定义一个表单类,继承自django.forms.Form。示例代码如下:
    # froms.py
    from django import forms  # 必须导入模块
    
    # 必须继承Form
    class MessageBoardForm(forms.Form):
        
        tiele = forms.CharField(max_length=32)  # 限制数据为字符串,最大长度为32
        page = forms.IntegerField()      # 限制为数字
        email = forms.EmailField()       # 限制为邮箱格式
    

    然后在视图中,根据GET还是POST请求来做相应的操作。如果是get请求,那么就返回一个空白表单,如果是post请求那个将提交上来的数据进行校验,示例代码:

    # views.py
    class IndexView(View):
        def get(self, request):
            form = MessageBoardForm()
            return render(request,'index.html',{'form':form})
        
        def post(self, request):
            from = MessageBoardForm(request.POST)  # 将post数据传给MessageBoardForm
            if form.is_valid():   # 验证数据
                return HttpResponse('success')
            else:
                print(form.errors)
                retutn HttpResponse('fail')
    

    用表单验证数据

    常用的Field

    charField

    用来接收文本

    • max_length:这个字段值的最大长度。
    • min_lenght:这个字段值的最小长度。
    • required:这个字段是否是必须的。默认是必须的。
    • 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。

    常用验证器

    在验证某个字段的时候,可以传递一个validators参数用来指定验证器,进一步对数据 进行过滤。验证器有很多,但是很多验证器我们其实已经通过这个Field或者一些参数就可以指定了。比如EmailValidator,我们可以通过EmailField来指定,比如MaxValueValidator,我们可以通过max_value参数来指定。以下是一些常用的验证器:

    1. MaxValueValidator:验证最大值
    2. MinValueValidator:验证最小值。
    3. MinLengthValidator:验证最小长度。
    4. MaxLengthValidator:验证最大长度。
    5. EmailValidator:验证是否是邮箱格式。
    6. URLValidator:验证是否是URL格式。
    7. RegexValidator:如果还需要更加复杂的验证,那么我们可以通过正则表达式的验证器:RegexValidator。比如现在要验证手机号码是否合格,那么我们可以通过以下代码实现:
    class MyForm(forms.Form):
         telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])
    

    自定义验证

    有时候对一个字段验证,不是一个长度,一个正则表达式能够写清楚的,还需要一些其他复杂的逻辑,那么我们可以对某个字段,进行自定义的验证。比如在注册的表单验证中,我们想要验证手机号码是否已经被注册过了,那么这时候就需要在数据库中进行判断才知道。对某个字段进行自定义的验证方式是,定义一个方法,这个方法的名字定义规则是:clean_fieldname。如果验证失败,那么就抛出一个验证错误。比如要验证用户表中手机号码之前是否在数据库中存在,那么可以通过以下代码实现:

    class MyForm(forms.Form):
        telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])
    
        def clean_telephone(self):
            telephone = self.cleaned_data.get('telephone')
            exists = User.objects.filter(telephone=telephone).exists()  # 判断User模型中是是否有telephone的数据存在
            if exists:      # 如果等于True
                raise forms.ValidationError("手机号码已经存在!")
            return telephone   # 否则返回telephone
    

    如果验证数据的时候,需要针对多个字段进行验证,那么可以重写clean方法。比如要在注册的时候,要判断提交的两个密码是否相等。那么可以使用以下代码来完成:

    class MyForm(forms.Form):
        telephone = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}",message='请输入正确格式的手机号码!')])
        pwd1 = forms.CharField(max_length=12)
        pwd2 = forms.CharField(max_length=12)
    
        def clean(self):
            cleaned_data = super().clean()
            pwd1 = cleaned_data.get('pwd1')
            pwd2 = cleaned_data.get('pwd2')
            if pwd1 != pwd2:
                raise forms.ValidationError('两个密码不一致!')
    

    ModelForm

    大家在写表单的时候,会发现表单中的Field和模型中的Field基本上是一模一样的,而且表单中需要验证的数据,也就是我们模型中需要保存的。那么这时候我们就可以将模型中的字段和表单中的字段进行绑定。
    比如现在有个Article的模型。示例代码如下:

    from django.db import models
    from django.core import validators
    
    
    class Article(models.Model):
        title = models.CharField(max_length=10,validators=[validators.MinLengthValidator(limit_value=3)])
        content = models.TextField()
        author = models.CharField(max_length=100)
        category = models.CharField(max_length=100)
        create_time = models.DateTimeField(auto_now_add=True)
    

    那么再写表单的时候,就不需要吧Article模型中的所有字段都一个个重写一遍了了,示例代码如下:

    from django import forms
    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = "__all__"
    

    MyForm是继承自forms.ModelForm,然后在表单中定义了一个Meta类,在Meta类中指定了model=Article,以及fields=“all”,这样就可以将Article模型中所有的字段都复制过来,进行验证。如果只想针对其中几个字段进行验证,那么可以给fields指定一个列表,将需要的字段写进去。比如只想验证title和content,那么可以使用以下代码实现:

    from django import forms
    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = ['title','content']
    

    如果要验证的字段比较多,只是除了少数几个字段不需要验证,那么可以使用exclude来代替fields。比如我不想验证category,那么示例代码如下:

    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            exclude = ['category']
    

    自定义错误消息

    使用ModelForm,因为字段都不是在表单中定义的,而是在模型中定义的,因此一些错误消息无法在字段中定义。那么这时候可以在Meta类中,定义error_messages,然后把相应的错误消息写到里面去。示例代码如下:

    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            exclude = ['category']
            error_messages  ={
                'title':{
                    'max_length': '最多不能超过10个字符!',
                    'min_length': '最少不能少于3个字符!'
                },
                'content': {
                    'required': '必须输入content!',
                }
            }
    

    save方法

    ModelForm还有save方法,可以在验证完成后直接调用save方法,就可以将这个数据保存到数据库中了。示例代码如下:

    form = MyForm(request.POST)
    if form.is_valid():
        form.save()
        return HttpResponse('succes')
    else:
        print(form.get_errors())
        return HttpResponse('fail')
    

    这个方法必须要在clean没有问题后才能使用,如果在clean之前使用,会抛出异常。另外,我们在调用save方法的时候,如果传入一个commit=False,那么只会生成这个模型的对象,而不会把这个对象真正的插入到数据库中。比如表单上验证的字段没有包含模型中所有的字段,这时候就可以先创建对象,再根据填充其他字段,把所有字段的值都补充完成后,再保存到数据库中。示例代码如下:

    # models.py
    class student(models.Model):
        username = models.CharField(max_length=100)
        password = models.CharField(max_length=100)
        telephone = models.CharField(max_length=11)
    
    # forms.py
    class zhuceForm(forms.ModelForm):
        pwd1 = forms.CharField(max_length=16, min_length=6)
        pwd2 = forms.CharField(max_length=16, min_length=6)
    
        def clean(self):
            cleaned_data = super().clean()
            pwd1 = cleaned_data.get('pwd1')
            pwd2 = cleaned_data.get('pwd2')
            if pwd1 != pwd2:
                raise forms.ValidationError(message='两次输入的密码不一致')
            return cleaned_data
    
        class Meta:
            model = student
            exclude = ['password']  # 不校验password
    
    @require_POST    # 现在请求为post
    def zhuce(request):
        form = zhuceForm(request.POST)     # 将post数据传给zhuceForm
        if form.is_valid():                # 验证数据
            student = form.save(commit=False)   # 只会生成一个user对象,而并不会保存到数据库中
            student.password = form.cleaned_data.get('pwd1')    # 得到user用户, 给用户指定password
            student.save()                                   # 保存到数据库
            return HttpResponse('success')
        else:
            return HttpResponse('fail')
    

    文件上传

    前端HTML代码实现:

    1. 在前端中,我们需要填入一个form标签,然后在这个form标签中指定enctype=“multipart/form-data”,不然就不能上传文件。
    2. 在form标签中添加一个input标签,然后指定input标签的name,以及type=“file”

    以上两步的示例代码:

    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="myfile">
    </form>
    

    后端的代码实现
    后端的主要工作是接收文件。然后存储文件。接收文件的方式跟接收POST的方式是一样的,只不过是通过FILES来实现。示例代码如下:

    def save_file(file):
        with open('somefile.txt','wb') as fp:
            for chunk in file.chunks():
                fp.write(chunk)
    
    def index(request):
        if request.method == 'GET':
            form = MyForm()
            return render(request,'index.html',{'form':form})
        else:
            myfile = request.FILES.get('myfile')
            save_file(myfile)
            return HttpResponse('success')
    

    使用模型来处理上传的文件

    在定义模型的时候,我们可以给存储文件的字段指定为FileField,这个Field可以传递一个upload_to参数,用来指定上传上来的文件保存到哪里。比如我们让他保存到项目的files文件夹下,那么示例代码如下:

    # models.py
    class Article(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        thumbnail = models.FileField(upload_to="files")
    
    
    # views.py
    def index(request):
        if request.method == 'GET':
            return render(request,'index.html')
        else:
            title = request.POST.get('title')
            content = request.POST.get('content')
            thumbnail = request.FILES.get('thumbnail')
            article = Article(title=title, content=content, thumbnail=thumbnail)
            article.save()
            return HttpResponse('success')
    

    调用完article.save()方法,就会把文件保存到files下面,并且会将这个文件的路径存储到数据库中。

    指定MEDIA_ROOT和MEDIA_URL

    以上我们是使用了upload_to来指定上传的文件的目录。我们也可以指定MEDIA_ROOT,就不需要在FielField中指定upload_to,他会自动的将文件上传到MEDIA_ROOT的目录下。

    MEDIA_ROOT = os.path.join(BASE_DIR,'media')
    MEDIA_URL = '/media/'
    

    然后我们可以在urls.py中添加MEDIA_ROOT目录下的访问路径。示例代码如下:

    from django.urls import path
    from front import views
    from django.conf.urls.static import static
    from django.conf import settings
    
    urlpatterns = [
        path('', views.index),
    ] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
    

    如果我们同时指定MEDIA_ROOT和upload_to,那么会将文件上传到MEDIA_ROOT下的upload_to文件夹中。示例代码如下:

    class Article(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        thumbnail = models.FileField(upload_to="%Y/%m/%d/")
    

    限制上传的文件拓展名

    如果想要限制上传的文件的拓展名,那么我们就需要用到表单来进行限制。我们可以使用普通的Form表单,也可以使用ModelForm,直接从模型中读取字段。示例代码如下:

    # models.py
    class Article(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        thumbnial = models.FileField(upload_to='%Y/%m/%d/',validators=[validators.FileExtensionValidator(['txt','pdf'])])
    
    # forms.py
    class ArticleForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = "__all__"
    

    上传图片

    上传图片跟上传普通文件是一样的。只不过是上传图片的时候Django会判断上传的文件是否是图片的格式(除了判断后缀名,还会判断是否是可用的图片)。如果不是,那么就会验证失败。我们首先先来定义一个包含ImageField的模型。示例代码如下:

    class Article(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        thumbnail = models.ImageField(upload_to="%Y/%m/%d/")
    

    因为要验证是否是合格的图片,因此我们还需要用一个表单来进行验证。表单我们直接就使用ModelForm就可以了。示例代码如下:

    class MyForm(forms.ModelForm):
        class Meta:
            model = Article
            fields = "__all__"
    注意:使用ImageField,必须要先安装Pillow库:pip install pillow
    
    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,567
精华内容 2,626
关键字:

django表单