ModelForm适用于前台验证和后台直接操作数据库的前后台未做分离,可以一次执行验证和保存数据的场景。
注意: 1. ModelForm里面没有删除方法,需要手动删除内容
2. ModelForm里面也可以像Form里面一样自定义clean_email()和clean()方法进行数据正确性的验证【post_clean()方法需要自定义try...except】
ModelForm之创建信息
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ url('modelFormDemo/', views.modelFormDemo), ]
views.py
from django.shortcuts import render, redirect, HttpResponse from app01 import models # ModelForm实例 from django import forms as modelForm from app01 import models class UserModelForm(modelForm.ModelForm): # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据 class Meta: # 说明指向,指定去执行U里面的内容 model = models.U # 指定类中的字段,告诉ModelForm帮我们处理多少字段 fields = '__all__' # 这里是帮我们处理所有字段 def modelFormDemo(request): if request.method == "GET": obj = UserModelForm() return render(request, 'modelFormDemo.html', {"obj":obj}) else : obj = UserModelForm(request.POST) if obj.is_valid(): data = obj.clean() print('正确数据:', data) # 这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data) obj.save() # 这个是ModelForm直接帮我们添加数据,同样也适用于多对多的情况 err = obj.errors print('错误数据:', err) return render(request, 'modelFormDemo.html', {"obj":obj})
templates/modelFormDemo.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> {#as_p是从BaseForm里面的方法#} <form action="/modelFormDemo/" method="POST"> {{ obj.as_p }} <input type="submit" value="提交"> </form> </body> </html>
models.py
from django.db import models class U(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) email = models.CharField(max_length=32) userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model): caption = models.CharField(max_length=32) def __str__(self): return self.caption
页面显示;
初始化数据库
python manage.py makemigrations python manage.py migrate
ModelForm之实时更新下拉框数据
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ url('edit_UserModelForm-(d+)/', fm.edit_UserModelForm), ]
views.py
from django.shortcuts import render, redirect, HttpResponse from app01 import models # ModelForm实例 from django import forms as modelForm class UserModelForm(modelForm.ModelForm): # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据 class Meta: # 说明指向,指定去执行U里面的内容 model = models.U # 指定类中的字段,告诉ModelForm帮我们处理多少字段 fields = '__all__' # 这里是帮我们处理所有字段 # 修改ModelForm内容 def edit_UserModelForm(request, nid): if request.method == "GET": obj_model = models.U.objects.get(id=nid) # 后台数据库的数据 obj = UserModelForm(instance=obj_model) # 把数据库的数据给了ModelForm return render(request, 'modelFormDemo.html', {"obj": obj}) # 进行页面显示 else: obj_model = models.U.objects.get(id=nid) # 后台数据库的数据 # 如果有instance则修改,没有则添加新数据 obj = UserModelForm(request.POST, instance=obj_model) # 获取前台提交的数据进行更新操作 if obj.is_valid(): data = obj.clean() print('正确数据:', data) # 这个是以前我们Model操作来进行增加数据:models.U.objects.create(**data) obj.save() # 这个是ModelForm直接帮我们添加数据,同样也适用于修改数据的情况 return render(request, 'edit_modelFormDemo.html', {"obj": obj, 'nid':nid}) # 进行页面显示
templates/edit_modelFormDemo.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> {#as_p是从BaseForm里面的方法#} <form action="/edit_UserModelForm-{{ nid }}/ " method="POST"> {{ obj.as_p }} <input type="submit" value="提交"> </form> </body> </html>
models.py
from django.db import models class U(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) email = models.CharField(max_length=32) userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model): caption = models.CharField(max_length=32) def __str__(self): return self.caption
页面显示;
初始化数据库
python manage.py makemigrations python manage.py migrate
ModelForm之save()方法分析
save()方法的集成度非常高,帮我们可以保存当前表的数据也可以保存多对多表的数据,一对多也是在当前表中,内部默认做了这些事
手动提交内容:
ModelForm之Meta的配置选项
ModelForm a.class Meta: model, # 对应Model的 fields = None, # 字段 exclude = None, # 排除字段 labels = None, # 提示信息 labels = {‘email’:‘邮箱’,’username’:’用户名’} help_texts = None, # 帮助提示信息 widgets = None, # 自定义插件 error_messages = None, # 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS) field_classes = None # 自定义字段类 (也可以自定义字段) localized_fields = ('birth_date',) # 本地化,如:根据不同时区显示数据 如: 数据库中 2016 - 12 - 27 04: 10:57 setting中的配置 TIME_ZONE = 'Asia/Shanghai' USE_TZ = True 则显示: 2016 - 12 - 27 12: 10:57 b.验证执行过程 is_valid -> full_clean -> 钩子 -> 整体错误 c.字典字段验证 def clean_字段名(self): # 可以抛出异常 # from django.core.exceptions import ValidationError return "新值" d.用于验证 model_form_obj = XXOOModelForm() model_form_obj.is_valid() model_form_obj.errors.as_json() model_form_obj.clean() model_form_obj.cleaned_data e.用于创建 model_form_obj = XXOOModelForm(request.POST) #### 页面显示,并提交 ##### # 默认保存多对多 obj = form.save(commit=True) # 不做任何操作,内部定义 save_m2m(用于保存多对多) obj = form.save(commit=False) obj.save() # 保存单表信息 obj.save_m2m() # 保存关联多对多信息 f.用于更新和初始化 obj = model.tb.objects.get(id=1) model_form_obj = XXOOModelForm(request.POST, instance=obj) ... PS: 单纯初始化 model_form_obj = XXOOModelForm(initial={...})
views.py
from django import forms as modelForm from app01 import models # 自动帮我们拿到了关联数据,且我们不需要操作什么,就可以直接实时刷新数据 class UserModelForm(modelForm.ModelForm): # 相当于在Model中U类的基础上有新添加了一个字段,属自定制内容 # 如果有跟数据库内的字段重名了,则会覆盖数据库字段的验证功能[Email验证功能] # email = forms.CharField() -->此时就是一个普通的char类型,遵循Form优先的原则 # 总结一下就是: 如果跟数据库不重名,则页面增加一条输入框; # 如果重名,则会覆盖原来【Form优先】 # 适用于那种一个月自动登录功能。可以从用户处多拿一个字段到后台进行验证功能 pwd = forms.CharField() # 此时数据库内并无此字段,这里添加后页面会增加此字段 class Meta: # 说明指向,指定去执行U里面的内容【只能指定一个Model类】 model = models.U # 指定类中的字段,告诉ModelForm帮我们处理多少字段 fields = '__all__' # 这里是帮我们处理所有字段,包括多对多的数据 # fields = ['name', 'email'] # 处理某几个字段 # exclude = ['name'] # 排除username的页面显示 labels = { 'name': '用户名', 'email': '邮 箱' } help_texts = { 'email':"*", 'name':'请输入姓名' } # 自定义插件 from django.forms import widgets as ws from django.forms import forms as ff widgets = { 'email': ws.Textarea() } error_messages = { '__all__':{‘required’:‘必填内容’},# 全局错误信息集 'name': {'required':'必填项', 'invalid':'格式错误'} } # 自定义字段类,进行二次验证 field_classes = { 'name': ff.EmailField # 虽然数据库时CharField,这里要求页面用EmailField进行正则验证 }
models.py
from django.db import models class U(models.Model): id = models.AutoField(primary_key=True) # AutoField必须是主键,才能自定义该列 name = models.CharField(max_length=32) email = models.CharField(max_length=32) userType = models.ForeignKey("UT", on_delete=True) # 1对多[无法用自定义,有约束关系] class UT(models.Model): caption = models.CharField(max_length=32) def __str__(self): return self.caption
ModelForm操作:http://www.cnblogs.com/wupeiqi/articles/6229414.html