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:Model
http://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的比较的更多相关文章

  1. Model&Form&ModelForm拾遗

    Model&Form&ModelForm拾遗 一.Model&Form&ModelForm Model:用于用户请求数据的验证(针对性弱),但有强大的数据库操作 For ...

  2. Django的model form组件

    前言 首先对于form组件通过全面的博客介绍,对于form我们应该知道了它的大致用法,这里我们需要明确的一点是,我们定义的form与model其实没有什么关系,只是在逻辑上定义form的时候字段名期的 ...

  3. model.form使用,配合form的钩子

    一次model.form的使用记录,配合form钩子的过程 在写信息采集功能的时候,需要添加资产信息,使用modelform组件减少工作量 官网介绍:版本1.9.https://docs.django ...

  4. Django Model Form

    ModelForm ModelForm结合了Form和Model,将models的field类型映射成forms的field类型,复用了Model和Model验证, 写更少的代码,并且还实现了存储数据 ...

  5. Django之路12——form modelform formset modelformset的各种用法

      首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用户提交的单个表单操作,字段可以用model中的表的字段来作为验证规则,适用于快速的 ...

  6. python3-开发进阶Django-form组件中model form组件

    Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...

  7. Django 的 model form 组件

    Django 的 model form 组件 Model Form 组件的由来 之前介绍过 Django 的 Form 组件(Django的Form表单)使用方法,Form 组件能够帮我们做三件事: ...

  8. 14 Django之Form和Model Form组件

    一.什么是Form 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用 ...

  9. form modelform formset modelformset的各种用法

    form modelform formset modelformset的各种用法   首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用 ...

  10. model form

    ModelForm 能允许我们通过一个 Model 直接创建一个和该模型的字段一一对应的表单,大大方便了表单操作. 下面来看一个例子. 首先我们有这样的 model: from django.db i ...

随机推荐

  1. Python如何规避全局解释器锁(GIL)带来的限制

    编程语言分类概念介绍(编译型语言.解释型语言.静态类型语言.动态类型语言概念与区别) https://www.cnblogs.com/zhoug2020/p/5972262.html Python解释 ...

  2. Proto3:风格

    本文介绍.proto文件的编码风格.遵循下面的惯例,可以使你的protocol buffer消息定义和它们对应的类连贯且已读. 注意,protocol buffer风格随时间变化一直在进步,所以可能你 ...

  3. nginx增加访问验证

    使用OpenSSL实用程序创建密码文件 如果您的服务器上安装了OpenSSL,则可以创建没有附加软件包的密码文件.我们将在/ etc / nginx配置目录中创建一个名为.htpasswd的隐藏文件来 ...

  4. 微软亚洲研究院开源图数据库GraphView

    我们很高兴地宣布,由微软亚洲研究院系统算法组开发的图数据库GraphView通过GitHub平台开源.GraphView是一款中间件软件,方便用户使用关系数据库SQL Server 或Azure SQ ...

  5. 记录R的一些黑魔法

    通路富集结果可视化 12345678 pathway<-read.table("PTC+_transcript_pep_supp_KEGG.txt",header=T,sep ...

  6. CSS中怎么设置元素水平垂直居中?

    记录怎么使用text-align与vertical-align属性设置元素在容器中垂直居中对齐.text-align与vertical-align虽然都是设置元素内部对齐方式的,但两者的用法还是有略微 ...

  7. 《前端之路》--- 重温 Egg.js

    目录 <前端之路>--- 重温 Egg.js 一.基础功能 > 日志系统包含了 四大层面的 日志对象, 分别是 App Logger.App CoreLogger.Context L ...

  8. 《自拍教程36》段位三_Python面向对象类

    函数只能面向过程,来回互相调用后顺序执行, 简单的编码项目,还能应付的过来, 复杂的大型项目,调用多了,就会乱. 如何才能不乱呢,可尝试下, 面向对象类的概念, 将现实世界的事物抽象成对象,将现实世界 ...

  9. 学h5前端开发前必知的三大流行趋势

    学h5前端开发前必知的三大流行趋势 随着互联网时代的飞速发展,各种互联网的Web应用程序层出不穷,很多人对于HTML5前端开发的过程充满了好奇,但是却没有了解到前端开发的未来发展趋势.下面,云慧学院专 ...

  10. VUE实现Studio管理后台(十三):按钮点选输入控件,input输入框系列

    按钮点选输入,是一个非常简单的控件,20分钟就能完成的一个控件.先看效果: 根据以前的设定,通过json数据动态生成这两个按钮,示例中这两个按钮对应的json代码: { label:'标题', val ...