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.99date=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.99date = 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.UUIDFieldname = models.URLFieldname = models.EmailFieldname = 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:57setting中的配置TIME_ZONE = 'Asia/Shanghai'USE_TZ = True则显示:2016-12-27 12:10:57b. 验证执行过程is_valid -> full_clean -> 钩子 -> 整体错误c. 字典字段验证def clean_字段名(self):# 可以抛出异常# from django.core.exceptions import ValidationErrorreturn "新值"d. 用于验证model_form_obj = XXOOModelForm()model_form_obj.is_valid()model_form_obj.errors.as_json()model_form_obj.clean()model_form_obj.cleaned_datae. 用于创建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={...})

# 你看不见我,

其实我有偷偷藏起来一份更加详细的博客 就在这里了。。。读书人的事情

转载于:https://www.cnblogs.com/shijieli/p/10191649.html

Django_modelform组件相关推荐

  1. 第四天:Vue组件的slot以及webpack

    插槽 认识slot 在生活中,很多地方都有插槽,电脑的USB插槽,插板中的电源插槽等. 插槽的目的是让我们原来的设备具备更多的扩展性.比如电脑的USB我们可以插入U盘.鼠标.键盘.硬盘.手机.音响等等 ...

  2. 第三天:Vue的组件化

    1.认识组件化 我们将一个完整的页面分成很多个组件,每个组件都用于实现页面的一个功能块,而每一个组件又可以进行细分. 组件化是Vuejs中的重要思想,它提供了一种抽象,让我们可以开发出一个个独立可复用 ...

  3. 客快物流大数据项目(六):Docker与虚拟机的形象比喻及组件介绍

    目录 Docker与虚拟机的形象比喻及组件介绍 一.Docker与虚拟机的形象比喻

  4. 2021年大数据Hadoop(二十六):YARN三大组件介绍

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 Yarn三大组件介绍 ResourceManager No ...

  5. android layout组件,Android UI学习 - Linear Layout, RelativeLayout

    1.一些常用的公共属性介绍 1) layout_width -宽 fill_parent: 宽度和父元素相同,wrap_content: 宽度随本身的内容所调整,或者指定 px值来设置宽 2) lay ...

  6. vue 拓扑组件_Authing 登录组件优化实践解析

    Authing Guard 是一种可嵌入的登录表单,可根据你的需求进行配置,它使你可以轻松添加各种社会化登录方式,以便你的用户可以无缝登录,并且在不同平台拥有一致的登录体验. Authing 2.0 ...

  7. 微信小程序自定义组件Component的简单使用

    首先为什么要使用component 这里列举2个例子, 1 如果项目中多个地方使用同一个弹框, 2 两个同事合作写一个界面, 这2中情况使用组件是比较好的选择 开始吧 第一步首先创建一个包用于存放组件 ...

  8. RelativeLayout布局,不希望文本盖住其他组件

    简单的图先看上一看 上面使用的是RelativeLayout布局(不要问为什么不用LinearLayout,因为最右边的信箱的右上角还会有个红点,相对布局直接些) 需要实现的效果是,TextView居 ...

  9. spring 组件基于注解的注册方式

    spring 中常用的组件标签有: @Controller:控制层 @Service:业务层 @Repository:数据层 @Component:普通的pojo注入到spring容器 组件注册方式: ...

最新文章

  1. 20个使用 Java CompletableFuture的例子
  2. java基础---JVM---java内存区域与内存溢出问题
  3. geoserver的api接口_geoserver REST使用
  4. firefox 3.0 在 windows 下的编译
  5. python回归预测例子_案例实战 | 逻辑回归实现客户流失预测(附Python代码与源数据)...
  6. [python] 列表解析式的高效与简洁
  7. iOS 的 XMPPFramework 简介
  8. Thinkphp3.2 中使用find_in_set
  9. Eclipse 使用
  10. pat 1006. 换个格式输出整数 (15)
  11. 用Proxy进行预处理
  12. Android布局基础知识
  13. 使用QT调用FFMPEG库部署到Android设备、完成视频音频应用开发
  14. asymptotic notation and recursion
  15. 【企业】掌握理查德·费曼学习法,提高学习效率
  16. 局域网助手(LanHelper) 1.96 注册码
  17. cesium教程-3(显示高度,海拔,经度,纬度)
  18. 习题 11.1 将例11.1的程序片断补充和改写成一个完整、正确的程序,用公用继承方式。在程序中应包括输入数据的函数,在程序运行时输入num,name,sex,age,addr的值,程序应输出以上。。
  19. c语言销售总额信息统计,C语言精简案例--销售统计直方图
  20. 在Word中引用参考文献

热门文章

  1. Python字符串translate()
  2. android学习笔记_Intent
  3. 根据应用场景人工智能技术有哪些分类?
  4. js可以控制文件上传的速度吗?
  5. 运行HelloJersey遇到异常解决方法
  6. VirtualBox中虚拟XP共享文件夹设置
  7. 复制slave-skip-errors及error查看
  8. 程序员面试金典——7.5平分的直线
  9. 【机器学习】端到端机器学习实践
  10. AB=0与伴随矩阵相互作用型题