1. 程式人生 > >Django之ModelForm

Django之ModelForm

分支 小型 RM ted per require AS 截取 字典

ModelForm:

應用場景:
- ModelForm - 中小型應用程序。因為ModelForm是依賴於models的
- Form - 大型應用程序 *

 1 ModelForm
 2     a.  class Meta:
 3             model,                           # 對應Model的
 4             fields=None,                     # 字段
 5             exclude=None,                    #
排除字段 6 labels=None, # 提示信息 7 help_texts=None, # 幫助提示信息 8 widgets=None, # 自定義插件 9 error_messages=None, # 自定義錯誤信息(整體錯誤信息from django.core.exceptions import NON_FIELD_ERRORS) 10 field_classes=None #
自定義字段類 (也可以自定義字段) 11 localized_fields=(birth_date,) # 本地化,如:根據不同時區顯示數據 12 如: 13 數據庫中 14 2016-12-27 04:10:57 15 setting中的配置 16 TIME_ZONE = Asia/Shanghai 17 USE_TZ = True 18 則顯示:
19 2016-12-27 12:10:57 20 b. 驗證執行過程 21 is_valid -> full_clean -> 鉤子 -> 整體錯誤 22 23 c. 字典字段驗證 24 def clean_字段名(self): 25 # 可以拋出異常 26 # from django.core.exceptions import ValidationError 27 return "新值" 28 d. 用於驗證 29 model_form_obj = XXOOModelForm() 30 model_form_obj.is_valid() 31 model_form_obj.errors.as_json() 32 model_form_obj.clean() 33 model_form_obj.cleaned_data 34 e. 用於創建 35 model_form_obj = XXOOModelForm(request.POST) 36 #### 頁面顯示,並提交 ##### 37 # 默認保存多對多 38 obj = form.save(commit=True) 39 # 不做任何操作,內部定義 save_m2m(用於保存多對多) 40 obj = form.save(commit=False) 41 obj.save() # 保存單表信息 42 obj.save_m2m() # 保存關聯多對多信息 43 44 f. 用於更新和初始化 45 obj = model.tb.objects.get(id=1) 46 model_form_obj = XXOOModelForm(request.POST,instance=obj) 47 ... 48 49 PS: 單純初始化 50 model_form_obj = XXOOModelForm(initial={...})
技術分享圖片
 1             - 1. 類 
 2                   class Foo(ModelForm):
 3                     class Meta:
 4                         # model = models.Role
 5                         # fields = "__all__"
 6                         # fields = [‘caption‘,]
 7                         # exclude = [‘catpion‘]
 8                         model = models.UserType
 9                         fields = "__all__"
10 
11                         error_messages = {
12                             title:{required:名稱不能為空,invalid:格式錯誤}
13                         }
14                         widgets = {
15                             title:wd.TextInput(attrs={class:c1})
16                         }
17                 
18             - 2. 添加
19                  GET:
20                     form = Foo()
21                  POST:
22                     form = Foo(data=request.POST)
23                     form.is_valid()
24                     form.cleaned_data
25                     form.erros
26                     form.save()
27             - 3. 修改
28                  GET:
29                     form = Foo(instance=obj)
30                  
31                  POST:
32                     form = Foo(instance=obj,dat=request.POST)
33                     ...
34                     form.save()
註意

使用

  1 from django.shortcuts import render,HttpResponse
  2 from app01 import models
  3 
  4 from django import forms
  5 from django.forms import fields as Ffields
  6 from django.forms import widgets as Fwidgets
  7 class UserInfoModelForm(forms.ModelForm):
  8 
  9     is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())  # 免登錄Checkbox字段
 10 
 11     class Meta:
 12         model = models.UserInfo
 13         fields = __all__
 14         # fields =  [‘username‘,‘email‘]
 15         # exclude = [‘username‘]
 16         labels = {
 17             username: 用戶名,
 18             email: 郵箱,
 19         }
 20         help_texts = {
 21             username: ...
 22         }
 23         widgets = {
 24             username: Fwidgets.Textarea(attrs={class: c1})
 25         }
 26         error_messages = {
 27             __all__:{            # 定義整體的錯誤信息
 28 
 29             },
 30             email: {
 31                 required: 郵箱不能為空,
 32                 invalid: 郵箱格式錯誤..,
 33             }
 34         }
 35         field_classes = {
 36             # ‘email‘: Ffields.URLField        # 和model中定義字段不同,這裏只能填寫類,可以覆蓋model中的字段屬性
 37         }
 38 
 39         # localized_fields=(‘ctime‘,)
 40 
 41     def clean_username(self):
 42         old = self.cleaned_data[username]
 43         return old
 44 
 45 class UserInfoForm(forms.Form):
 46     username = Ffields.CharField(max_length=32)
 47     email = Ffields.EmailField()
 48     user_type = Ffields.ChoiceField(
 49         choices=models.UserType.objects.values_list(id,caption)
 50     )
 51 
 52     def __init__(self, *args, **kwargs):
 53         super(UserInfoForm,self).__init__(*args, **kwargs)
 54         self.fields[user_type].choices = models.UserType.objects.values_list(id,caption)
 55 ‘‘‘
 56 源碼截取: 
 57     def save(self, commit=True):
 58         if commit:
 59             # If committing, save the instance and the m2m data immediately.
 60             self.instance.save()
 61             self._save_m2m()
 62         else:
 63             # If not committing, add a method to the form to allow deferred
 64             # saving of m2m data.
 65             self.save_m2m = self._save_m2m
 66 ‘‘‘
 67 
 68 def index(request):
 69     if request.method == "GET":
 70         obj = UserInfoModelForm()
 71         return render(request,index.html,{obj: obj})
 72     elif request.method == "POST":
 73         obj = UserInfoModelForm(request.POST)
 74         if obj.is_valid():
 75             # obj.save()
 76             instance = obj.save(False)            # self.instance 當前model對象
 77             instance.save()                        # 僅保存當前類對應的表,相當於源碼中if條件的self.instance.save()
 78             obj.save_m2m()                        # 相當於源碼中if條件的self._save_m2m(),else分支中做了賦值self.save_m2m = self._save_m2m
 79 
 80 
 81         # print(obj.is_valid())
 82         # print(obj.cleaned_data)
 83         # print(obj.errors.as_json())
 84         return render(request,index.html,{obj: obj})
 85 
 86 
 87 def user_list(request):
 88     li = models.UserInfo.objects.all().select_related(user_type)
 89     return render(request,user_list.html,{li: li})
 90 
 91 def user_edit(request, nid):
 92     # 獲取當前id對象的用戶信息
 93     
 94     if request.method == "GET":
 95         user_obj = models.UserInfo.objects.filter(id=nid).first()
 96         mf = UserInfoModelForm(instance=user_obj)            # 顯示用戶已經存在數據
 97         return render(request,user_edit.html,{mf: mf, nid: nid})
 98     elif request.method == POST:
 99         user_obj = models.UserInfo.objects.filter(id=nid).first()
100         mf = UserInfoModelForm(request.POST,instance=user_obj)
101         if mf.is_valid():
102 
103             mf.save()
104         else:
105             print(mf.errors.as_json())
106         return render(request,user_edit.html,{mf: mf, nid: nid})
107         
108 # modelform小結        
109     1. 生成HTML標簽:class Meta: ...
110     2. 顯示用戶已經存在數據 :mf = xxxModelForm(instance=ModelObj)
111     3. 額外的標簽, is_rmb = Ffields.CharField(widget=Fwidgets.CheckboxInput())  #  7天免登錄Checkbox字段
112     4. 各種驗證 is_valid() -> 各種鉤子...  # 方法和Form中的鉤子完全一樣
113     5.     mf.save()
114         #
115         instance = mf.save(False)
116         instance.save()
117         mf.save_m2m()

Django之ModelForm