博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django Form表单学习总结
阅读量:6573 次
发布时间:2019-06-24

本文共 4041 字,大约阅读时间需要 13 分钟。

Form中添加自定义的验证:

   1.对特定字段属性的验证;
   2.包含多字段的验证.
先创建一个简单的Form:

from django import formsclass ContactForm(forms.Form):    subject = forms.CharField(max_length=100)    message = forms.CharField()    sender = forms.EmailField()    recipients = MultiEmailField()    cc_myself = forms.BooleanField(required=False)

1.验证特定字段属性

使用表单子类中的clean_<fieldname>()方法 -- 通过表单中的字段名称替换.这个方法完成特定属性相关的验证,这个验证与字段的类型无关.这个方法没有任何传入的参数.你需要查找self.cleaned_data中该字段的值,记住此时它已经是一个python对象而不是表单中提交的原始字符串(它位于cleaned_data中是因为字段clean()方法已经验证过一次数据).

例如,在ContactForm中,我们想确保recipients字段始终包含'fred@example.com'.这是特定于我们这个表单的验证,所以我们打算将它放在通用的MultiEmailField类中.编写一个运行在recipients字段上的验证方法:

from django import formsclass ContactForm(forms.Form):    #Everything as before    ...    def clean_recipients(self):        data = self.cleaned_data['recipients']        if 'fred@example.com' not in data:            raise forms.ValidationError('You havev forgotten Fred!')        # Always return a value to use as the new cleaned data, even if this method didn't change it        return data

2.验证相互依赖的字段

假设我们添加另外一个需求到联系人表单中:如果cc_myself字段为True,那么subject必须包含单词'help'.这个验证包含多个字段,所以表单clean()方法是个不错的地方.

注意,这里讨论的是表单clean()方法,上面有提到一个字段clean()方法.区别字段和表单之间的差别非常重要,字段是单个数据,表单是字段的集合.
在调用表单clean()方法的时候,所有字段的验证方法已经执行完,所以self.cleaned_data填充的是目前为止已经合法的数据.所以需要记住一个事实,你需要验证的字段可能没有通过初始的字段检查!

from django import formsclass ContactForm(forms.Form):    # Everything as before    ...    def clean(self):        cleaned_data = super(ContactForm, self).clean()        cc_myself = cleaned_data.get('cc_myself')        subject = cleaned_data.get('subject')        if cc_myself and subject:            # Only do something if both fields are valid so far.            if 'help' not in subject:                raise forms.ValidationError("Did not send for 'help' in the subject despite CC'ing yourself")

在这段代码中,如果抛出验证错误,表单将在表单的顶部显示(通常是)描述该问题的一个错误信息。

注意,示例代码中super(ContactForm, self).clean()的调用是为了保证维持父类中的验证逻辑。

3.多表单提交的外键处理

假设有多个模型之间存在外键关系,那么在同一个页面同时提交这几个表单的处理方法:

建立几个模型:

from django.db import modelsclass Store(models.Model):    ...class Deport(models.Model):    s_name = models.ForeignKey(Store)    ...class Address(models.Model):    s_name = models.ForeignKey(Store)    ...

给这几个模型分别建立模型表单.

由于其中两个表使用了1个外键约束,如果同时提交和保存数据会导致数据表中的s_name_id字段值为NULL.为了解决这个问题,我们采用延迟提交给数据库的方式.
ModelForm的save()方法接受一个可选的commit关键字参数,其值为True/False.如果save()commit=False,那么它将返回一个还没保存到数据库的模型实例对象.这种情况下,你需要调用该返回的模型实例的save()方法.这样你可以在保存数据之前进行一些自定义的处理.commit默认为True.

from django.views.generic.base import Viewclass Store_Add(View):    ...    def post(self, request):        sf = StoreForm(request.POST)        df = DeportForm(request.POST)        af = AddressForm(request.POST)        if sf.is_valid() and df.is_valid() and af.is_valid():            store = sf.save()            dform = df.save(commit=False)    # 将来自DeportForm的数据暂存为一个模型实例,其中s_name字段为空            dform.s_name = store            dform.save()            aform = af.save(commit=False)            aform.s_name = store            aform.save()        ...

4.从表单中访问字段

可以通过表单fields属性访问字段:

#models.pyfrom django.db import modelsclass Publisher(models.Model):    name = models.CharField(max_length=30)    address = models.CharField(max_length=50)    website = models.URLField()    def __str__(self):        return self.name#forms.pyfrom django import formsfrom myapp.models import Publisherclass PublisherForm(forms.ModelForm):    class Meta:        model = Publisher        fields = '__all__'>>> form = PublisherForm()>>> form.fields# 返回一个有序字典对象,键为Form中的字段名,值为fields对象OrderedDict([('name', 
), ('address',
), ('website',
)])可以使用字典的方法对Form的字段进行一些操作,例如:form.fields.update({'website': forms.CharField(widget=forms.TextInput()})后者动态的对某一个字段的属性进行修改:form.fields['website'].initial = self.request.user.website

fields对象的一些参考文档中的说明.

参考:http://python.usyiyi.cn/translate/django_182/ref/forms/validation.html#validating-fields-with-clean
   https://segmentfault.com/a/1190000007183873

转载于:https://www.cnblogs.com/thunderLL/p/7510493.html

你可能感兴趣的文章
iphone socket讲解
查看>>
CAS机制详解
查看>>
odoo开发笔记 -- 翻译机制及导入.po文件
查看>>
运维邮件
查看>>
Sql异常①
查看>>
横向无缝滚动
查看>>
PreparedStatement设置时间
查看>>
CF533C:Board Game(博弈)
查看>>
HDU5389:Zero Escape(dp & 类背包)
查看>>
jQ常见数组问题
查看>>
SEO优化:WordPress发布文章主动推送到百度,加快收录保护原创
查看>>
小学期学习总结一
查看>>
ScrollGridView 标题不变化 内容变化
查看>>
LeetCode - 16. 3Sum Closest
查看>>
LeetCode - 7. Reverse Integer
查看>>
MFC下运行控制台不显示黑屏
查看>>
算法练习——聪明的情侣
查看>>
Java多线程系列 面试题
查看>>
AOP jdk动态代理
查看>>
windows常用操作
查看>>