Model、Form、ModelForm的比较
Model、Form、ModelForm
本节内容:
1:Model
2:Form
3:Model Form
|
1
2
3
|
http://www.cnblogs.com/wupeiqi/articles/6144178.html 武sir:Form组件http://www.cnblogs.com/wupeiqi/articles/6216618.html 武sir:Modelhttp://www.cnblogs.com/wupeiqi/articles/6229414.html 武sir:ModelForm |
Model ==> 强大的数据库操作,弱小的数据验证。
Form ==>强大的数据验证
ModelForm ===>二者结合,强大的数据验证,适中的数据库操作。在ModelForm是能够封装一个model对象。
1:Model
对于Model来说,他的验证是需要自己去创建一个model对象,然后去进行判断
model:
针对单一字段 :full_clean
针对多个的字段: clean full_clean -- >字段正则判定 -- >clean方法(钩子)
他是没有最终产物
views:
def fm(request):
obj = models.News(title='root')
##full_clean就进行了验证,如果要是有errors的话,就直接报错,所以在进行验证的时候,我们要自己做try判断
obj.full_clean() ##进行model的验证。里面的def clean 方法
obj.save() ##报错 django.core.exceptions.ValidationError: {'__all__': ['title不能是root']}
return render(request,"form.html",locals())
models:
from django.db import models
from django.core.exceptions import ValidationError class News(models.Model):
title = models.CharField(max_length=) ##验证错误会输出到errors中去
def clean(self):
if self.title == "root":
raise ValidationError("title不能是root")
model的源码分析:
def full_clean(self, exclude=None, validate_unique=True):
"""
Call clean_fields(), clean(), and validate_unique() on the model.
Raise a ValidationError for any errors that occur.
"""
errors = {}
if exclude is None:
exclude = []
else:
exclude = list(exclude) try:
self.clean_fields(exclude=exclude) ####执行单个字段的验证
except ValidationError as e:
errors = e.update_error_dict(errors) # Form.clean() is run even if other validation fails, so do the
# same with Model.clean() for consistency.
try:
self.clean() ####执行clean的方法验证
except ValidationError as e:
errors = e.update_error_dict(errors) ###如果错误,把错误添加到errors中 # Run unique checks, but only for fields that passed validation.
if validate_unique:
for name in errors:
if name != NON_FIELD_ERRORS and name not in exclude:
exclude.append(name)
try:
self.validate_unique(exclude=exclude)
except ValidationError as e:
errors = e.update_error_dict(errors) if errors: ###如果有错误,就直接报错了,so 我们要自己去views视图中去判断,try
raise ValidationError(errors)
2:Form
有着强大的验证功能: 具体看源码。
对于Form来说,是当一个请求来了,直接进行post数据的验证,如果是错误会有一个obj.errors的错误对应。
Form :有强大的验证
针对单一字段的: full_clean
自定义针对单一字段的: clean_username
针对多个字段的: clean 【or】port_clean (这个是不能出现异常,只能添加异常) is_valid() -- >full_clean () -->
-->每个字段的正则,每个字段clean_字段名()
-->clean_form -->clean(钩子)
-->_post_clean(钩子) 验证后的产物:clean_date 或obj.errors
Form中要获取数据库的实时数据:
两种方式:
|
1
|
第二种方式,虽然是可以用但是它的可定制性差。是需要依赖model的 |

浏览器中:显示

3:ModelForm
Model、Form、ModelForm三者的结合:
在公司比较大的时候:比如说:
models文件是放在A项目中
forms是放在B项目中 froms是没办法导入models中的数据的。
我们就让Form单独的做数据验证,而model就单纯的做数据库操作各司其职是完美的。 但是dajngo还存在了一种叫ModelForm的东西,他是结合了model和Form的功能。
Form和ModelForm的继承关系:
Form:
继承关系:
UserForm -- > Form -- >BaseForm
ModelForm:
继承关系:
NewsModelForm -->ModelForm -->BaseModelForm -->BaseForm 所以modelForm和Form是有同一个祖宗的,Form中的BaseForm的功能,ModelForm也一样可以使用。
ModelForm的简单使用:
from django.db import models
from django.core.exceptions import ValidationError class User_Type(models.Model):
name = models.CharField(max_length=)
def __str__(self):
return self.name class Tags(models.Model):
name = models.CharField(max_length=)
def __str__(self):
return self.name class News(models.Model):
title = models.CharField(max_length=)
type = models.ForeignKey(User_Type,on_delete=models.CASCADE,blank=True,null=True)
tag = models.ManyToManyField(Tags) ##验证错误会输出到errors中去
def clean(self):
if self.title == "root":
raise ValidationError("title不能是root")
model
from django.forms import Form ##Form要继承的
from django.forms import ModelForm ##ModelForm继承
from web import models class NewsModelForm(ModelForm):
class Meta:
model = models.News ##里面必须要有一个model,因为他是对每个models类做增删改查的
fields = "__all__" ##指定了类,要需要指定要处理哪几个字段 __all__是全部字段 def mf(request):
if request.method == "GET":
obj = NewsModelForm()
if request.method == "POST":
obj = NewsModelForm(data=request.POST) ##传入进行验证
if obj.is_valid():
#models.News.objects.create(**obj.cleaned_data) ##以前Form的时候添加数据要这样写
obj.save() ##modelform现在可以直接save就可以,save的时候可以保存一对多、多对多的数据
else:
print(obj.errors)
return render(request, "mf.html", locals())
template: [是不需要执行上面的什么__init__方法、和第二种方法]直接就可以实时了。
<form action="" method="post">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit">
</form>

ModelForm的另一个功能:修改
urls:
|
1
|
re_path('edit-(\d+).html',views.edit) |
views:
class NewsModelForm(ModelForm):
class Meta:
model = models.News ##里面必须要有一个model,因为他是对每个models类做增删改查的
fields = "__all__" ##指定了类,要需要指定要处理哪几个字段 __all__是全部字段 def edit(request,nid):
if request.method == "GET":
model_obj = models.News.objects.get(id=nid) ##获取model对象
obj = NewsModelForm(instance=model_obj)
else:
model_obj = models.News.objects.get(id=nid)
obj = NewsModelForm(request.POST,instance=model_obj) ##修改的时候是需要instance 的!如果没有则默认就是增加数据的
if obj.is_valid():
# obj.save() ##他里面的源码默认是commit=True 会帮你第三张表一起修改了。而在django是可以自己手动指定修改的
mobj = obj.save(commit=False) #要是commit为False的话,他会返回一个model的对象、点击commit看源码
mobj.save() ##保存自己表中数据
mobj.save_m2m() ##修改第三张表中的数据,而你要在这二者之间是可以做,一些你想做的事情的 return render(request,"mf.html",locals())
template:
<form action="" method="post">
{% csrf_token %}
{{ obj.as_p }}
<input type="submit">
</form>
ModelForm中Meta的详解
# from web import forms
from django.forms import Form ##Form要继承的
from django.forms import ModelForm ##ModelForm继承
from web import models
from django.forms import widgets as ws
from django import forms
from django.forms import fields class NewsModelForm(ModelForm):
email = fields.CharField() ##这个会叫把原来的email字段覆盖,变成了CharField的属性验证
pwd = fields.CharField() ##还能够增加一个News中model之外的字段,很有用。的
class Meta:
model = models.News ##里面必须要有一个model,因为他是对每个models类做增删改查的
fields = "__all__" ##指定了类,要需要指定要处理哪几个字段 __all__是全部字段
#exclude = ["email",] ##排除某个字段
labels = {"name":"名字","title":"标题"} ##显示字段的label
help_texts = {"title":"*"} ##显示字段的help_texts "*"我们代表为必填
widgets = {
"name":ws.Textarea(attrs={"class":"c1"}) ##自定义字段标签。和加属性
}
error_messages ={
"email":{"required":"必填","invalid":"格式错误"} ##自定义错误提示
}
field_classes = {
"name":forms.EmailField ##ModelForm的字段是model中的,name在model是CharField的,而我们可以更改他的验证以邮箱格式进行验证
}
localized_fields = ("ctime",) ##model中是UTC时间,显示的时候 按本地时间输出
动态生成ModelForm表单
def Dynamic_Model_Form(admin_class,form_change=True):
class Meta:
model = admin_class.model
fields = "__all__"
##排除exclude的字段
admin_class.form_change = False ##用户前端页面是否生成p标签的判断
if form_change:
admin_class.form_change = True
exclude = admin_class.readonly_fields
def __new__(cls,*args,**kwargs):
for field_name in cls.base_fields: ##字段都包含在了cls.base_fields中
filed_obj = cls.base_fields[field_name]
#添加属性
filed_obj.widget.attrs.update({'class':'form-control'}) ##
return ModelForm.__new__(cls)
DyModelForm = type("Foo",(ModelForm,),{"Meta":Meta,"__new__":__new__})
return DyModelForm
Model、Form、ModelForm的比较的更多相关文章
- Model&Form&ModelForm拾遗
Model&Form&ModelForm拾遗 一.Model&Form&ModelForm Model:用于用户请求数据的验证(针对性弱),但有强大的数据库操作 For ...
- Django的model form组件
前言 首先对于form组件通过全面的博客介绍,对于form我们应该知道了它的大致用法,这里我们需要明确的一点是,我们定义的form与model其实没有什么关系,只是在逻辑上定义form的时候字段名期的 ...
- model.form使用,配合form的钩子
一次model.form的使用记录,配合form钩子的过程 在写信息采集功能的时候,需要添加资产信息,使用modelform组件减少工作量 官网介绍:版本1.9.https://docs.django ...
- Django Model Form
ModelForm ModelForm结合了Form和Model,将models的field类型映射成forms的field类型,复用了Model和Model验证, 写更少的代码,并且还实现了存储数据 ...
- Django之路12——form modelform formset modelformset的各种用法
首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用户提交的单个表单操作,字段可以用model中的表的字段来作为验证规则,适用于快速的 ...
- python3-开发进阶Django-form组件中model form组件
Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...
- Django 的 model form 组件
Django 的 model form 组件 Model Form 组件的由来 之前介绍过 Django 的 Form 组件(Django的Form表单)使用方法,Form 组件能够帮我们做三件事: ...
- 14 Django之Form和Model Form组件
一.什么是Form 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用 ...
- form modelform formset modelformset的各种用法
form modelform formset modelformset的各种用法 首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用 ...
- model form
ModelForm 能允许我们通过一个 Model 直接创建一个和该模型的字段一一对应的表单,大大方便了表单操作. 下面来看一个例子. 首先我们有这样的 model: from django.db i ...
随机推荐
- XX系统测试总结报告
XX系统测试总结报告 1 引言 1.1 编写目的 编写该测试总结报告主要有以下几个目的 1. 通过对测试结果的分析,得到对软件质量的评价 2. 分析测试的过程,产品,资源,信息, ...
- Mysql(或者sqlite), Mongo中update Column + 1
Mysql(或者sqlite), Mongo中update Column + 1 有类似以下需求,在数据库表里有一个字段,记录了一个count,然后又时候需要在count的基础上加上某个数字,比如1. ...
- springboot框架中集成thymeleaf引擎,使用form表单提交数据,debug结果后台获取不到数据
springboot框架中集成thymeleaf引擎,使用form表单提交数据,debug结果后台获取不到数据 表单html: <form class="form-horizontal ...
- python下载神通板砖有声版
背景 前端时间在喜马拉雅上偶然听到牛大宝说的有声小说神通板砖,说的很是幽默,听的正起劲的时候开始收费了,于是我就在网上找了下看看有没有免费版,一搜果然有,但该网站上广告太多了,于是我就写了个小脚本可以 ...
- [讨论] 平台建设,我们从架构中去掉kafka?
目 录 1. 概述... 2 2. 原有结构(带kafka)... 2 3. 改造后的结构(去掉kafka)... 3 4. 对比... 4 1. ...
- 算法入门——二分查找,旅行商问题,大O表示法
一. 算法入门 博主在市面上发现了很多,很多有关书算法的书籍,但是真正能够让初学者易懂的算法书籍,只是一点点,以下我讲以 Aditya Bhargava写的一本关于算法的入门书籍,为参考,这本书非常的 ...
- Description Resource Path Location Type cvc-complex-type.2.4.c: The matching 解决问题
2017-03-02 10:08:03,112 [localhost-startStop-1] ERROR org.springframework.web.servlet.DispatcherServ ...
- node中fs模块 - fs.open() fs.read() fs.write() fs.close()
var fs = require('fs') fs.open('./a.txt', 'a+', function(err, fd) { // 打开文件后 创建缓冲区放置数据 ), // 读取多少字节 ...
- 怎么用一行HTML代码搭建一个谷歌镜像?
<iframe src="google.com"></iframe>
- apache搭建Tomcat集群(Cluster)
搭建集群: apache:特点处理静态资源(html 图片 js等) apache的请求操作,Cluster工具 tomcat:特点处理动态资源 apache+tomcat(apache是web服 ...