Django_modelform组件
modelForm 组件
概念
将数据库与form 组件结合用起来的中间插件
与 form 组件的区别
form组件的难处:
form 可以实现 对数据的验证以及 form 的表单标签的生成
但是她做不到一点就是无法将数据库串联起来,无法做到数据的传回
比如编辑页面的时候无法拿到当前正要被编辑的值
modelfom 组件在 form组件的基础上进行升级 :
自动创建 form 类 (将model类 转换成 form类)
在 from类手动创建的是时候就可以发现,form 的创建和 model 的数据库几乎完全一致
而modelform 可以帮我们直接实现这个操作而不在需要手动创建
直接和 model 对应上,对于 model 的增删改查会更加的简单便捷
创建关联
用form 组件的形式创建
class Book(models.Model):
title=models.CharField(max_length=32)
price=models.DecimalField(max_digits=8,decimal_places=2) # 999999.99
date=models.DateField()
publish=models.ForeignKey("Publish")
authors=models.ManyToManyField("Author")
class BookForm(forms.Form):
title = forms.CharField(max_length=32,label="书籍名称")
price = forms.DecimalField(max_digits=8, decimal_places=2,label="价格") # 999999.99
date = forms.DateField(
label="日期",
widget=widgets.TextInput(attrs={"type":"date"})
)
publish=forms.ModelChoiceField(queryset=Publish.objects.all())
authors=forms.ModelMultipleChoiceField(queryset=Author.objects.all())
用modelform 组件的形式创建
class BookForm(ModelForm):
class Meta:
model=Book # 制定要被转换的表
fields="__all__" # 控制要被转换的字段 , __all__ 表示所有字段 ,除了 用 __all__ 的时候对多个字段使用的时候用列表的形式
# fields=["title","price"] # 除了 用 __all__ 的时候用字符串形式,对多个字段使用的时候用列表的形式
常见仓鼠:
from django.forms import ModelForm
#在视图函数中,定义一个类,比如就叫StudentList,这个类要继承ModelForm,在这个类中再写一个原类Meta(规定写法,并注意首字母是大写的)
#在这个原类中,有以下属性(部分): class StudentList(ModelForm):
class Meta:
# 对应的Model中的类
model =Student # 注意这里千万别加 "," 会识别成元组导致报错 # 字段,如果是__all__,就是表示列出所有的字段
fields = "__all__"
# fields = ["name","age"] # 指定显示某些字段 # 排除的字段
# exclude = ["name","age"]
exclude = none# error_messages 错误信息
# 自定义错误信息(整体错误信息from django.core.exceptions import NON_FIELD_ERRORS)
error_messages = {
'__all__':{}, # 整体的错误信息放在这里
'name':{'required':"用户名不能为空",}, # 个别字段的错误信息单独显示
'age':{'required':"年龄不能为空",},
}
# widgets 用法,比如把输入用户名的input框给为Textarea# 首先得导入模块
from django.forms import widgets as wid #因为重名,所以起个别名
widgets = { # 这个widgets只是一个参数名,不要搞混
"name":wid.Textarea(attrs={"class":"c1"}) #还可以自定义属性
} # labels 自定义在前端显示的名字
labels= {
"name":"用户名"
}
# help_texts 显示帮助信息
help_texts={
"name":"这里写你的名字"
}
# field_classes 自定义字段类
field_classes={
'email':fields.URLField #这里只能填类,不能加括号,加上括号就变成对象了。
# 这是把邮箱的默认邮箱类自定义成url类了。
}
ps:
在没有用 form 以及 modelform 之前, 这两个本质都是一样,都是保存的就是字符串而已,其实是没有意义的
只有 form 以及 modelform 才可以对他们进行校验,在这时候 UUIDField , EmailField 之类的才有意义
因为只有 form 以及 modelform 才可以将 models.xxxx 转换成 forms.xxx 的时候进行自己的 is_vaild 方法进行相关的校验
name = models.CharField
name = models.UUIDField
name = models.URLField
name = models.EmailField
name = models.IPAddressField
数据传回
和 form 组件的对比
如果不用ModelForm,对于要显示原来的数据,需要挨个取一遍值,
如果ModelForm,只需要加一个 instance=obj(obj是要修改的数据库的一条数据的对象)就可以得到同样的效果
对当前编辑的对象的数据的取回,在form 组件的时候是无法操作的
form 类在实例化对象的时候无法接受参数
modelform 组件可以 以instance参数接受一个对象
save 的使用
对于数据的编辑更新和新建,modelform 类统一使用 .save() 方法
当 当前的 modelform 对象中没有 instance参数的时候默认添加一个新对象
当 当前的 modelform 对象中有 instance参数的时候会按照参数的中的对象进行更新操作
(不给对象参数的话怎么知道要编辑哪一个呢?)
def addbook(request):
if request.method == "POST":
form = BookForm(request.POST)
if form.is_valid():
form.save() # form.model.objects.create(request.POST)
return redirect("/books/")
else:
return render(request, "add.html", locals())
form=BookForm()
return render(request, "add.html", locals()) def editbook(request, edit_book_id):
# 被编辑的书的对象
edit_book = Book.objects.filter(pk=edit_book_id).first()
if request.method == "POST":
form = BookForm(request.POST, instance=edit_book)
if form.is_valid():
form.save() # edit_book.update(request.POST)
return redirect("/books/")
form=BookForm(instance=edit_book)
return render(request, "edit.html",locals())
ModelForm的验证
用form方法的时候,验证功能的函数其实是写在BaseForm里的:UserInfoForm-->继承了Form--->继承了BaseForm(is_valid......)
点击提交的时候,modelform也可以做验证。UserInfoModelForm-->继承了ModelForm--->继承了BaseModelForm--->继承了BaseForm(is_valid......)
UserInfoModelForm下面也应该有obj.is_valid(), obj.cleaned_data, obj.errors 等方法。
ModelForm 做验证的时候与Form方法是一样的。
我们可以像使用Form类一样自定义局部钩子方法和全局钩子方法来实现自定义的校验规则。
如果我们不重写具体字段并设置validators属性的话,ModelForm是按照模型中字段的validators来校验的。
总结
modelform 组件在 form 组件的基础上,保留了 form 组件的全部功能
而且 更加简单的实现了与model 表的映射创建
并且新增了与model 表的链接得以可以对当前操作的对象直接操作
知识点整合
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={...})
# 你看不见我,
其实我有偷偷藏起来一份更加详细的博客 就在这里了。。。读书人的事情
Django_modelform组件的更多相关文章
- Python 目录指引
1.0 Python 基础整合 1.1 变量 1.2 数据类型 1.3 基础语法 1.4 文件操作 1.5 函数 1.6 生成器 1.7 迭代器 1.8 装饰器 1.9 字符集 2.0 Python ...
- ExtJS 4.2 评分组件
上一文章是扩展ExtJS自带的Date组件.在这里将创建一个评分组件. 目录 1. 介绍 2. 示例 3. 资源下载 1. 介绍 代码参考的是 Sencha Touch 2上的一个RatingStar ...
- react组件的生命周期
写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...
- react-router 组件式配置与对象式配置小区别
1. react-router 对象式配置 和 组件式配置 组件式配置(Redirect) ----对应---- 对象式配置(onEnter钩子) IndexRedirect -----对应-- ...
- Angular2入门系列教程3-多个组件,主从关系
上一篇 Angular2项目初体验-编写自己的第一个组件 好了,前面简单介绍了Angular2的基本开发,并且写了一个非常简单的组件,这篇文章我们将要学会编写多个组件并且有主从关系 现在,假设我们要做 ...
- Angular2入门系列教程2-项目初体验-编写自己的第一个组件
上一篇 使用Angular-cli搭建Angular2开发环境 Angular2采用组件的编写模式,或者说,Angular2必须使用组件编写,没有组件,你甚至不能将Angular2项目启动起来 紧接着 ...
- .NET Core 首例 Office 开源跨平台组件(NPOI Core)
前言 最近项目中,需要使用到 Excel 导出,找了一圈发现没有适用于 .NET Core的,不依赖Office和操作系统限制的 Office 组件,于是萌生了把 NPOI 适配并移植到 .NET C ...
- .NetCore中的日志(1)日志组件解析
.NetCore中的日志(1)日志组件解析 0x00 问题的产生 日志记录功能在开发中很常用,可以记录程序运行的细节,也可以记录用户的行为.在之前开发时我一般都是用自己写的小工具来记录日志,输出目标包 ...
- BootStrap_02之全局样式及组件
1.BootStrap指定的四种屏幕尺寸: ①超大PC屏幕--lg(large):w>=1200px: ②中等PC屏幕--md(medium):1200px>w>=992px: ③P ...
随机推荐
- arcgis api 3.x for js 入门开发系列六地图分屏对比(附源码下载)
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...
- iOS----------developerDiskImage
真机测试时提示Could not find Developer Disk Image.这该怎么办???? 这是由于真机系统过高或者过低,Xcode中没有匹配的配置包文件,我们可以通过这个路径进入配置包 ...
- java.lang.NoSuchFieldError异常
原因就是主项目的xml文件和库项目中的xml文件 命名一样,导致库项目中的xml文件被主项目覆盖,所以库项目就找不到xml中的相关id,就报异常了. 解决方法:修改主项目中的xml文件命名,不要和 ...
- Visual Studio无法调试
一.最近Visual studio调试不起来,运行完报错 二.解决方法 打开 调试>>>>选项>>>>常规>>>对ASP.NET启用 ...
- json-gson:.isJsonNull()问题-堆栈溢出
不用管我下面的第一个答案.我读得太快了. 看起来这是一个简单的例子,文件撒谎-或者至少是被误解了.幸运的是,代码并不是那么简单,而且gson是一个开源项目. 这是 JsonObject.get(Str ...
- Netty学习笔记(四) 简单的聊天室功能之服务端开发
前面三个章节,我们使用了Netty实现了DISCARD丢弃服务和回复以及自定义编码解码,这篇博客,我们要用Netty实现简单的聊天室功能. Ps: 突然想起来大学里面有个课程实训,给予UDP还是TCP ...
- java设计模式——适配器模式 Java源代码
前言:适配器模式就是把一个类的接口变换成客户端所能接受的另一种接口,从而使两个接口不匹配而无法在一起工作的两个类能够在一起工作.通常被用在一个项目需要引用一些开源框架来一起工作时,这些框架的内部都有一 ...
- MongoDB 聚合分组取第一条记录的案例及实现
关键字:MongoDB: aggregate:forEach 今天开发同学向我们提了一个紧急的需求,从集合mt_resources_access_log中,根据字段refererDomain分组,取分 ...
- windows环境下安装yaf框架
windows环境下安装yaf框架 在windows下安装yaf框架 准备工作: php环境(过程略,wamp,xampp,phpstudy都行,php版本大于5.3) git工具(需要从github ...
- thinkphp v5.1 开发笔记
一.安装TP5.1 1.使用git安装 <1>下载Tp git clone https://github.com/top-think/think tp5 <2>安装核心库 gi ...