本节内容:

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区别的更多相关文章

  1. Django 的 model form 组件

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

  2. Model&Form&ModelForm拾遗

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

  3. Django的model form组件

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

  4. django基础 -- 10.form , ModelForm ,modelformset

    一.生成页面可用的 HTML标签 1.form 所有内置字段 Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label ...

  5. Django之model.form创建select标签

    前言 之前我们学习了form表单验证用户输入格式和自动创建HTML,那么如果用户创建select标签时怎么办呢,先来看下这个东西: models.py 数据格式: class UserInfo(mod ...

  6. Django 中的Form、ModelForm

    一.ModelForm 源码 class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass def modelform_fact ...

  7. 3 django系列之Form表单在前端web界面渲染与入库保存

    author: 温柔易淡(Leo),欢迎技术交流与拍砖 preface 我们在前端写表单的时候,其实可以使用django自带的forms功能来实现,特别是在处理 修改已经存在数据 的场景特别好用,下面 ...

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

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

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

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

随机推荐

  1. 【JMeter_18】JMeter逻辑控制器__吞吐量控制器<Throughput Controller>

    吞吐量控制器<Throughput Controller> 业务逻辑: 他的实际作用似乎跟吞吐量扯不上什么关系.就是单纯的控制控制器下的子节点被执行的次数或被执行比列,该控制器默认为多线程 ...

  2. 事务的特性ACID、隔离级别

    1.事务特性ACID 1.1 事务的四大特性 1.原子性(Atomicity) 事务包装的一组sql,要么都执行成功,要么都失败.这些操作是不可分割的. 2.一致性(Consistency) 数据库的 ...

  3. psp表格

    陈康杰psp表格 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 10 10 Estimate 估计这个任务 ...

  4. 使用SpringCloud Stream结合rabbitMQ实现消息消费失败重发机制

    前言:实际项目中经常遇到消息消费失败了,要进行消息的重发.比如支付消息消费失败后,要分不同时间段进行N次的消息重发提醒. 本文模拟场景 当金额少于100时,消息消费成功 当金额大于100,小于200时 ...

  5. 一个简单的 react 实例: < TodoList >

    <  react     TodoList:  > 组件: //引入React : import React from 'react'; //组件 class TodoList exten ...

  6. ViewPager2 学习

    ViewPager2 延迟加载数据 ViewPager2 延迟加载数据 ViewPager 实现预加载的方案 ViewPager2 实现预加载的方案 总结 ViewPager 实现预加载的方案 背景 ...

  7. JSON类库Jackson优雅序列化Java枚举类

    1. 前言 在Java开发中我们为了避免过多的魔法值,使用枚举类来封装一些静态的状态代码.但是在将这些枚举的意思正确而全面的返回给前端却并不是那么顺利,我们通常会使用Jackson类库序列化对象为JS ...

  8. express高效入门教程(4)

    4.静态文件 4.1.普通处理静态文件的方法 在./views/index.html文件中去引入另一个css文件index.css,index.css文件放在public/css目录下,目录结构是这样 ...

  9. Docker入门——理解Docker的核心概念

    1 前言 相信不少人听过这么一句话: 人类的本质是复读机. 在软件开发领域也一样,我们总是想寻找更好地方式复制优秀的逻辑或系统.最核心的方法是抽取通用逻辑和组件,把差异化的东西接口化或配置化,达到复用 ...

  10. 第一步:安装centos_8

    关于centos的安装其实大部分时候都是在虚拟机环境下安装. 好处无疑有这几个:方便,快速,主要就是整出事情了我可以直接删了重装 我这边是在vmware下进行一个安装 vmware我这边给出下载链接: ...