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 ...
随机推荐
- 上海启动5G试用!104页PPT,为你深度解析5G终端的创新和机遇
文章发布于公号[数智物语] (ID:decision_engine),关注公号不错过每一篇干货. 来源:国泰君安证券 作者:分析师王聪.张阳.陈飞达 导读:2019年是5G元年,各大品牌将陆续推出5G ...
- [Python][Scrapy 框架] Python3 Scrapy的安装
1.方法(只介绍 pip 方式安装) PS.不清楚 pip(easy_install) 可以百度或留言. cmd命令: (直接可以 pip,而不用跳转到 pip.exe目录下,是因为把所在目录加入 P ...
- selenium-启动浏览器(二)
selenium下启动浏览器,有两种方法 以 chromedrvier.exe 为例 1. chromedrvier.exe 与 python 启动程序 python.exe 在同一个目录下则可直接使 ...
- python之单元测试_生成测试报告
(1)HTMLTestRunner.py的下载路径:https://pan.baidu.com/s/1Yk2E8d8bIo5_rmpussOE9Q 提取码:0jae (2)HTMLTestRunner ...
- 如何在Asp.Net中使用JQueryEasyUI
JQueryEasyUI的基本信息: 官方下载 官方演示 官方文档 一.jQuery easyUI下载后解压的文件目录如下图: demo:JQueryEasyUI的一些示例页面,在项目使用可以将该目录 ...
- 先vue-cli,再nuxt试试路由
https://segmentfault.com/a/1190000007933349
- HBase工具:如何查看HBase的HFile
root@root:~/Desktop/sourceCodes/hbase-2.1.1/bin# ./hbase Usage: hbase [<options>] <command& ...
- [LeetCode] 10. 正则表达式匹配
题目链接:https://leetcode-cn.com/problems/regular-expression-matching/ 题目描述: 给定一个字符串 (s) 和一个字符模式 (p).实现支 ...
- 步步深入:MySQL架构总览->查询执行流程->SQL解析顺序(转)
文章转自 http://www.cnblogs.com/annsshadow/p/5037667.html https://www.cnblogs.com/cuisi/p/7685893.html
- 百度杯”CTF比赛 九月场 123
进去后让登录,先看源码有提示 进到user.php 后发现是空的,看了wp才知道,有bak 下载下来直接爆破 但是那个1990是蛮骚的 直接进去登录 登录成功后是空的,走fd看看是怎么过 的 改包然后 ...