一, ModelForm
源码
- class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass):
- pass
- def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
- formfield_callback=None, widgets=None, localized_fields=None,
- labels=None, help_texts=None, error_messages=None,
- field_classes=None):
- ?
1.2 实例理解
- ?
- #!/usr/bin/env python
- # -*- coding:utf-8 -*-
- import re
- from django import forms
- from django.forms import widgets as Mwidgets
- from django.forms import fields as Mfields
- from django.forms import ValidationError
- from cmdb import models
- class UserModelForm(forms.ModelForm):
- session_checkbox = Mfields.ChoiceField(
- choices=(
- (0, "默认每次输入密码"),
- (1, "一周免登 6"),
- (4, "一个月免登 6"),
- ),
- # widget=Mwidgets.CheckboxInput
- )
- is_login = Mfields.CharField(
- label= "一年免登 6",
- widget= Mwidgets.CheckboxInput()
- )
- class Meta:
- model = models.User
- # fields = "__all__" #所有字段都验证生成
- fields = ["name", "email", "wechat", "phone",] #从表中选出字段验证生成
- exclude = ["password", "ctime"] #除了选中的字段都验证生成
- labels = { #前端生成 labels 给字段别名, 使用中文不使用数据库字段名
- "name": "用户名:",
- "email": "邮箱:",
- "wechat": "微信",
- "phone": "手机号:"
- }
- widgets = {
- "name": Mwidgets.TextInput(attrs={"class": "c1", "value": "请输入用户名"}),
- "email": Mwidgets.Textarea(attrs={"class": "c2"})
- }
- error_messages = {
- "email": {
- "required": "邮箱必填",
- "invalid": "邮箱格式有误"
- },
- "phone": {
- "required": "电话号码为必填",
- "invalid": "手机号有误"
- }
- }
- #因为本身 ModelForm 继承了 Form
- #所以可以用 Form 预留的钩子来做验证
- def clean_phone(self):
- """
- class BaseForm:
- .....
- def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
- ....
- self.is_bound = data is not None or files is not None
- self.data = {} if data is None else data
- """
- #上面为 BaseForm 源码, 当在 POST 方法中实例化 Form 或者 ModleForm 时, requestPOST 就被传入 self.data 中了
- #所以 所有字典的方法 self.data 都可用了, 建议使用 dict.get() 方式取数据
- phone_number = self.data.get("phone", None)
- if not phone_number:
- raise ValidationError("电话号不能为空")
- mobile_pattern = '^13[0-8]{1}\d{8}'
- if not re.match(mobile_pattern, str(phone_number)):
- raise ValidationError("手机号格式有误")
- return phone_number # 将正确的 value 电话号返回去
- #以下为预留钩子源码
- # if hasattr(self, 'clean_%s' % name):
- # value = getattr(self, 'clean_%s' % name)()
- # self.cleaned_data[name] = value 返回的正确值被加入到 self.cleaned_data[name] 中, name 为字段名
来源: http://www.bubuko.com/infodetail-2771602.html