Django之ModelForm
一、说明
应用场景:
- ModelForm - 中小型应用程序。因为ModelForm是依赖于models的
- Form - 大型应用程序 *
二、参数说明
ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 labels=None, # 提示信息 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={...})
注意事项:
注意事项: - 1. 类 class Foo(ModelForm): class Meta: # model = models.Role # fields = "__all__" # fields = ['caption',] # exclude = ['catpion'] model = models.UserType fields = "__all__" error_messages = { 'title':{'required':'名称不能为空','invalid':'格式错误'} } widgets = { 'title':wd.TextInput(attrs={'class':'c1'}) } - 2. 添加 GET: form = Foo() POST: form = Foo(data=request.POST) form.is_valid() form.cleaned_data form.erros form.save() - 3. 修改 GET: form = Foo(instance=obj) POST: form = Foo(instance=obj,dat=request.POST) ... form.save()
三、实例
示例1、简单增删改查
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class MyModelForm(ModelForm): class Meta: model = models.XXX.objects.get(xxx) fields = "__all__" _m = type("Meta", (object,), {"model": models.XXX.objects.get(xxx), "fields": "__all__"}) MyModelForm = type("MyModelForm", (ModelForm,), {"Meta": _m}) # 如果request.method == "GET",即初始化页面,不带初始值 model_form_obj = MyModelForm() # 如果request.method == "GET",即初始化页面,带初始值 obj = models.XXX.objects.get(pk=pk) model_form_obj = MyModelForm(instance=obj)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<form method="POST" novalidate> {% csrf_token %} {# {{ form.as_p }}#} {# <div>===================</div>#} {% for item in form %} <div>{{ item.name }}:{{ item }}</div> {% endfor %} <input type="submit"> </form>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
return render(request, "xxx.html", {"form":model_form_obj})
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.forms import ModelForm class MyModelForm(ModelForm): class Meta: model = models.XXX.objects.get(xxx) fields = "__all__" _m = type("Meta", (object,), {"model": models.XXX.objects.get(xxx), "fields": "__all__"}) MyModelForm = type("MyModelForm", (ModelForm,), {"Meta": _m}) model_form_obj = MyModelForm(data=request.POST,files=request.FILES) model_form_obj.save()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class MyModelForm(ModelForm): class Meta: model = models.XXX.objects.get(xxx) fields = "__all__" _m = type("Meta", (object,), {"model": models.XXX.objects.get(xxx), "fields": "__all__"}) MyModelForm = type("MyModelForm", (ModelForm,), {"Meta": _m}) # 如果request.method == "GET",即初始化页面,带初始值 obj = models.XXX.objects.get(pk=pk) model_form_obj = MyModelForm(instance=obj) # 如果request.method == "POST",即页面post上来进行修改 model_form_obj = MyModelForm(data=request.POST,files=request.FILES,instance=obj) model_form_obj.save()
示例2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,redirect from app01 import models from django.forms import ModelForm class TestModelForm(ModelForm): class Meta: model = models.UserInfo fields = "__all__" # fields = ("user","email") error_messages = { "user":{"required":"用户名不能为空"}, "email":{"required":"email不能为空","invalid":"邮箱格式错误"}, } def test(request): # return TemplateResponse(request,[] or ['xiaohaohao.tml',"test.html"],{"k1":"v1"}) if request.method == "GET": form = TestModelForm() context = { "form":form, } return render(request,"test.html",context) else: form = TestModelForm(request.POST) if form.is_valid(): print(form.cleaned_data) form.save() # ModelForm具有models功能,可直接save # models.UserInfo.objects.create(**form.cleaned_data) # return redirect("http://www.baidu.com") context = { "form":form, } return render(request,"test.html",context) def edit(request,nid): obj = models.UserInfo.objects.filter(id=nid).first() if request.method == "GET": form = TestModelForm(instance=obj) context = { "form":form, } return render(request,"edit.html",context) else: form = TestModelForm(instance=obj,data=request.POST,files=request.FILES) if form.is_valid(): form.save() return redirect("http://www.baidu.com")
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>test页面</h1> <form method="POST" > {% csrf_token %} {# {{ form.as_p }}#} <p>name:{{ form.user }}{{ form.user.errors.0 }}</p> <p>email:{{ form.email }}{{ form.email.errors.0 }}</p> <p>ug:{{ form.ug }}{{ form.ug.errors.0 }}</p> <p>m2m:{{ form.m2m }}{{ form.m2m.errors.0 }}</p> <input type="submit"> </form> </body> </html>
示例3 注意,1对多、多对多也是这样form.save()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""first_review URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.0/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), re_path("app01/",include("app01.urls")), re_path("testmodelform/",include("testmodelform.urls")), ] ############## /testmodelform/urls.py from django.contrib import admin from django.urls import path,re_path,include from testmodelform import views urlpatterns = [ re_path("index/",views.index), re_path("user_add/",views.UserAdd.as_view()), re_path("user_edit/(?P<pk>\d+)/",views.UserEdit.as_view()), ]
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.db import models # Create your models here. class UserInfo(models.Model): username = models.CharField(max_length=16) password = models.CharField(max_length=16) email = models.EmailField() def __str__(self): return "{}-{}".format(self.username,self.email)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# -*- coding:utf-8 -*- from django.forms import fields,models,widgets,Form class UserInfoForm(Form): username = fields.CharField(required=True,max_length=16,error_messages={"required":"不能为空"}) password = fields.CharField(required=True,max_length=16,widget=widgets.PasswordInput,error_messages={"required":"不能为空"}) email = fields.EmailField(required=True,error_messages={"required":"不能为空"})
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.shortcuts import render,HttpResponse,redirect from testmodelform import models from django.views import View from testmodelform import form from django.forms import ModelForm,widgets class UserInfoModelForm(ModelForm): class Meta: #这个类必须写,而且名字必须是这个 model = models.UserInfo #这个model也是固定的,注意不加s, # fields = "__all__" #代表所有的字段,但是你也可以指定单个的字段 fields = ["username","password","email"] exclude = [] error_messages = { "username":{"required":"用户名不能为空"}, "password":{"required":"密码不能为空"}, "email": {"required": "email不能为空", "invalid": "邮箱格式错误"}, } widgets = { "password":widgets.PasswordInput, } class UserAdd(View): ###### 普通 ###### # def get(self,request): # # return render(request,"user_add.html") # # def post(self,request): # data = request.POST # res = models.UserInfo.objects.create( # username=data.get("username"), # password=data.get('password'), # email=data.get("email") # ) # print(res.id) # return HttpResponse("OK") ###### form ###### # def get(self, request): # obj = form.UserInfoForm(initial={"username":"用户名"}) # return render(request, "user_add.html",{"form":obj}) # # def post(self, request): # obj = form.UserInfoForm(request.POST,request.FILES) # if obj.is_valid(): # data = obj.cleaned_data # res = models.UserInfo.objects.create( # username=data.get("username"), # password=data.get('password'), # email=data.get("email") # ) # print(res.id) # return HttpResponse("OK") # else: # print(obj.errors) # return render(request,"user_add.html",{"form":obj}) ###### modelform ###### def get(self,request): obj = UserInfoModelForm(initial={"username":"用户名"}) context = { "form":obj, } return render(request,"user_add.html",context) def post(self,request): obj = UserInfoModelForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) obj.save() return HttpResponse("ok") else: return render(request,"user_add.html",{"form":obj}) class UserEdit(View): def get(self,request,pk): obj = models.UserInfo.objects.get(pk=pk) user_obj = UserInfoModelForm(instance=obj) context = { "pk":pk, "form":user_obj } return render(request,"user_edit.html",context) def post(self,request,pk): obj = models.UserInfo.objects.get(pk=pk) user_obj = UserInfoModelForm(request.POST,instance=obj) if user_obj.is_valid(): user_obj.save() return HttpResponse("ok") else: return render(request, "user_edit.html", {"form": obj})
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>user_edit</h1> <form action="/testmodelform/user_add/" method="POST" novalidate> {% csrf_token %} {# 普通 #} {# <div>用户名:<input type="text" name="username"></div>#} {# <div>密码:<input type="password" name="password"></div>#} {# <div>邮箱:<input type="email" name="email"></div>#} {# form #} {# <div>{{ form.username }}{{ form.username.errors.0 }}</div>#} {# <div>{{ form.password }}{{ form.password.errors.0 }}</div>#} {# <div>{{ form.email }}{{ form.email.errors.0 }}</div>#} {# modelform #} <div>{{ form.username }}{{ form.username.errors.0 }}</div> <div>{{ form.password }}{{ form.password.errors.0 }}</div> <div>{{ form.email }}{{ form.email.errors.0 }}</div> <input type="submit" value="submit"> </form> </body> </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>useredit</h1> <form action="/testmodelform/user_edit/{{ pk }}/" method="POST" novalidate> {% csrf_token %} {{ form.username }} {{ form.password }} {{ form.email }} <input type="submit"> </form> </body> </html>