1. 程式人生 > >Django 中的Form、ModelForm

Django 中的Form、ModelForm

NPU form ces 免登陸 理解 ror back require post

一、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為字段名

Django 中的Form、ModelForm