Django 中的Form、ModelForm

一、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, "一周免登陆"),
            (4, "一个月免登陆"),
        ),
        # widget=Mwidgets.CheckboxInput
    )

    is_login = Mfields.CharField(
        label= "一年免登陆",
        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为字段名

猜你喜欢

转载自www.cnblogs.com/shiqi17/p/9665051.html