Django之Model、Form、ModelForm区别
本节内容:
1:Model https://www.cnblogs.com/shuai1991/p/10844662.html
2:Form https://www.cnblogs.com/shuai1991/p/10763508.html https://www.cnblogs.com/shuai1991/p/10766649.html
3:ModelForm https://www.cnblogs.com/shuai1991/p/10852254.html
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=32) ##验证错误会输出到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的功能。
ModelForm的简单使用:
from django.db import models
from django.core.exceptions import ValidationError class User_Type(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name class Tags(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.name class News(models.Model):
title = models.CharField(max_length=32)
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
Django之Model、Form、ModelForm区别的更多相关文章
- Django 的 model form 组件
Django 的 model form 组件 Model Form 组件的由来 之前介绍过 Django 的 Form 组件(Django的Form表单)使用方法,Form 组件能够帮我们做三件事: ...
- Model&Form&ModelForm拾遗
Model&Form&ModelForm拾遗 一.Model&Form&ModelForm Model:用于用户请求数据的验证(针对性弱),但有强大的数据库操作 For ...
- Django的model form组件
前言 首先对于form组件通过全面的博客介绍,对于form我们应该知道了它的大致用法,这里我们需要明确的一点是,我们定义的form与model其实没有什么关系,只是在逻辑上定义form的时候字段名期的 ...
- django基础 -- 10.form , ModelForm ,modelformset
一.生成页面可用的 HTML标签 1.form 所有内置字段 Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label ...
- Django之model.form创建select标签
前言 之前我们学习了form表单验证用户输入格式和自动创建HTML,那么如果用户创建select标签时怎么办呢,先来看下这个东西: models.py 数据格式: class UserInfo(mod ...
- Django 中的Form、ModelForm
一.ModelForm 源码 class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass def modelform_fact ...
- 3 django系列之Form表单在前端web界面渲染与入库保存
author: 温柔易淡(Leo),欢迎技术交流与拍砖 preface 我们在前端写表单的时候,其实可以使用django自带的forms功能来实现,特别是在处理 修改已经存在数据 的场景特别好用,下面 ...
- python3-开发进阶Django-form组件中model form组件
Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...
- Django之路12——form modelform formset modelformset的各种用法
首先上结论: form适用于对单个表单的操作,并且需要对每个字段的验证规则自定义. modelform:适用于对用户提交的单个表单操作,字段可以用model中的表的字段来作为验证规则,适用于快速的 ...
随机推荐
- turtle 画国旗
代码实现: import turtle import time import os def draw_square(org_x, org_y, x, y): turtle.setpos(org_x, ...
- (二)groupId和artifactId
groupId一般分为多个段,这里我只说两段,第一段为域,第二段为公司名称. 域又分为org.com.cn等等许多,其中org为非营利组织,com为商业组织. 举个apache公司的tomcat项目例 ...
- pip安装报错: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProxyError('Cannot connect to proxy
pip安装报错 解决办法: pip install selenium -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
- BUAA_OO_2020_Unit4_总结博客
BUAA_OO_2020_Unit4_总结 2020年春季学期第十六周,OO第四单元即最终章落下帷幕,本单元是利用Java进行UML类图的解析,完成对类图.顺序图.状态图的内部查询操作与简单的规则判断 ...
- 在windows上安装docker
开启Hyper-V 添加方法非常简单,把以下内容保存为.cmd文件,然后以管理员身份打开这个文件.提示重启时保存好文件重启吧,重启完成就能使用功能完整的Hyper-V了. pushd " ...
- cc22a_demo_c++重载自增自减操作符-代码示范
cc22a_demo_c++重载自增自减操作符-代码示范 #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespa ...
- 【服务器】VMware Workstation Pro虚拟机搭建本地服务器CentOs7和宝塔面板(保姆式教程)
内容繁多,请耐心跟着流程走,在过程中遇到问题请在下面留言. 前言 这几天一直在复习thinkphp5.1,学习环境是phpStudy8.1,但是遇到了文件有缓存的问题(thinkphp5.1.39,修 ...
- 利用salt stack pillar安装多组keepalived
利用salt stack pillar安装多组keepalived 环境描述 在生产环境中,需要搭建三套keepalived环境,3个master和3个backup,要安装的软件和配置文件,虽然不是很 ...
- python动态柱状图图表可视化:历年软科中国大学排行
本来想参照:https://mp.weixin.qq.com/s/e7Wd7aEatcLFGgJUDkg-EQ搞一个往年编程语言动态图的,奈何找不到数据,有数据来源的欢迎在评论区留言. 这里找到了一个 ...
- 3、尚硅谷_SSM高级整合_使用ajax操作实现删除的功能
点击删除的时候,要删除联系人,这里同点击编辑按钮一样给删除按钮添加点击事件的时候不能使用 $(".delete_btn").click(function(){ }); 这种方式,因 ...