Django Forms 功能

2023年 1月 4日 59.3k 0

1. 自动生成HTML表单元素

Widget,用来渲染成HTML元素的工具。

  • 指定小部件
1
2
3
4
5
6
from django import forms

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)

CommentForm().as_table() 输出值

1
<tr><th><label for="id_name">Name:</label></th><td><input   name="name" type="text" /></td></tr>\n<tr><th><label for="id_url">Url:</label></th><td><input   name="url" type="url" /></td></tr>\n<tr><th><label for="id_comment">Comment:</label></th><td><textarea cols="40"   name="comment" rows="10">\r\n</textarea></td></tr>

指定表单字段为 Textarea 小部件,而不是默认的 TextInput 小部件。

  • 自定义小部件的样式
1
2
3
4
class CommentFormClass(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
    url = forms.URLField()
    comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

CommentFormClass().as_table() 输出值

1
<tr><th><label for="id_name">Name:</label></th><td><input     name="name" type="text" /></td></tr>\n<tr><th><label for="id_url">Url:</label></th><td><input   name="url" type="url" /></td></tr>\n<tr><th><label for="id_comment">Comment:</label></th><td><input   name="comment" size="40" type="text" /></td></tr>
  • 输出形式

通常我们在 views.py 函数中,实例化 Form ,然后传入模板。

1
2
3
4
5
from django.shortcuts import render
from .forms import CommentForm
    pass
    form = CommentForm()
    return render(request, 'my_template.html', {'form': form})

在模板中使用,my_template.html 。根据 {{ form }},所有的表单字段和属性,将通过 Django 的模板语言拆分成 HTML 标记 。

1
2
3
4
5
<form action="/my_template_data/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

可选的表单渲染项:{{ form.as_table }} 以表格的形式将它们渲染在tr标签中{{ form.as_p }} 将它们渲染在p 标签中{{ form.as_ul }} 将它们渲染在ul标签中

2. 检查表单数据的合法性

为了能够快速、有效的校验提交的数据。Django Forms提供了对表单数据合法性校验的支持。校验流程

  • 继承 form.Form ,创建自定义 Form 类 MyForm
  • 使用 request.POST,实例化 MyForm类
  • 合法性校验,is_valid()
  • 获取合法数据或返回错误提示

下面是一个简单的例子:forms.py

1
2
3
from django import forms
class Contact(forms.Form):
    email = forms.EmailField(error_messages={'required':u'邮箱不能为空'})

views.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
from django.http import HttpResponse
from .forms import Contact
def my_view(request):
    form = Contact(request.POST)
    if not form.is_valid():
        return HttpResponse(
            json.dumps({
                "result": False,
                "data": [],
                "message": form.errors,
                "code": -1
            }), content_type='application/json')
    else:
        return HttpResponse(
            json.dumps({
                "result": True,
                "data": [],
                "message": form.cleaned_data.get('email'),
                "code": -1
            }), content_type='application/json')

如果接口从POST数据中,获取到了email字段,并且为邮箱字段,就返回True。否则,返回错误提示。

2.1 继承 Form

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import re
from django import forms
from django.core.validators import validate_email
from django.core.exceptions import ValidationError

class ContactForm(forms.Form):
    cn8_re = re.compile(ur'^[-_\w\u4e00-\u9fa5]{3,16}$')
    SEXUAL_CHOICES = (
    (0, u'男'),
    (1, u'女')
    )
    # 正则校验
    nick_name = forms.RegexField(min_length=3, max_length=16, label=u'昵称',
                                 error_messages={
                                     'required': u'昵称不能为空,长度3~16中英文及_-',
                                     'invalid': u'请输入合法昵称(3~16位以内中英文字符).'
                                 }, regex=cn8_re)
    # 指定函数校验validate_email,可以指定多个                             
    email = forms.EmailField(validators=[validate_email])   
    # 指定为Choice                          
    gender = forms.ChoiceField(choices=SEXUAL_CHOICES, required=False, label=u'性别')
    # 指定长度
    password_0 = forms.RegexField(min_length=8, max_length=20, label=u'密码',
                                  error_messages=''egex=pwd_regex)
    password_1 = forms.RegexField(min_length=8, max_length=20, label=u'确认密码',
                                  error_messages='pwd_error_msg', regex=pwd_regex)
    # 重载clean函数,实现自定义的校验                             
    def clean(self):
        if self.cleaned_data.get('password_0') != self.cleaned_data.get('password_1'):
            self.add_error('password_1', u"两次密码输入不匹配.")
            raise ValidationError(u"两次密码输入不匹配.")

        return self.cleaned_data

Django Forms提供了大量的Field用于数据有效性校验, ‘Field’, ‘CharField’, ‘IntegerField’, ‘DateField’, ‘TimeField’, ‘DateTimeField’, ‘DurationField’, ‘RegexField’, ‘EmailField’, ‘FileField’, ‘ImageField’, ‘URLField’, ‘BooleanField’&mldr;能满足绝大多数的场景。

2.2 结合Model

如果 POST 提交的数据,是为了操作 Model 数据,为什么不能简单点,直接用 Model 初始化 Form 的字段呢?当然可以。models.py

1
2
3
4
from django.db import models
class Contact(models.Model):
    title = models.CharField(max_length=30)
    content = models.CharField(max_length=20)

form.py

1
2
3
4
5
6
from django.forms import ModelForm
from .models import Contact
class ConotactForm(ModelForm):
    class Meta:
        model = Contact
        field = ('title','content')  #只显示model中指定的字段

Form 只需要继承 ModelForm 类,并在 Meta 中指定映射的 Model,Django Forms 会自动在 Form 中添加 field 指定的字段。而不需要,像继承 forms.Form ,一个字段一个字段添加。

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论