一次model.form的使用记录,配合form钩子的过程

在写信息采集功能的时候,需要添加资产信息,使用modelform组件减少工作量

官网介绍:版本1.9.https://docs.djangoproject.com/en/1.9/ref/forms/models/

对应关系,modelform会把model装换成form的对应字段(每个模型字段都有一个对应的默认表单字段):

对应关系如下表:

外键,和多对多比较特殊(是queryset的形式):

外键对应的模型是:ChoiceField

多对多对应的是:MultipleChoiceField

默认的情况下,对应关系生成后:

模型有blank=True约束的话,form表单的required会设置成False,即不会进行非空校验。

表单字段的标签被设置为模型字段的verbosename,第一个字符大写。

表单字段的helptext被设置为model字段的helptext。

我的使用记录,钩子字段的解释

model.model

class  Asset(models.Model):
sin = models.CharField(max_length=64,blank=True,null=True)#sin号
asset_choic = (
(1,"网络设备"),
(2,"服务器"),
(3,"机柜"),
(4,"其他"), u_count = models.CharField('位置(几u到几u)',max_length=16,) #大小

modelform

from django.forms import ModelForm
from django.forms import widgets
from django.core.exceptions import ValidationError
class AddAsset(ModelForm):
  #下方为钩子,跟form中的钩子一致,需要clean_开头,ValidationError抛出你定义的错误信息
def clean_u_count(self): u_count = self.cleaned_data.get('u_count')
if u_count:
if len(u_count) < 6 and "-" in u_count :
return u_count
else:
           raise ValidationError('请按格式填写,xx-xx,xx为数字') class Meta: #Meta元数据
model = Asset #关联哪张表 #fields = "__all__" 这个显示Asset中所有的字段 #exclude =['xxx'] 指定的列不会显示,实例化时不会初始化,在save()中也不会出现数据 fields = ['types','hostname','sin', 'price','status','server_ipmi',
'ip','u_count','idc','cabinet','bussins','contact' ] widgets = { #widgets允许你自定义标签例如:
'hostname': Textarea(attrs={'cols': 80, 'rows': 20}),
#model.form会自动生成id ;id_字段, } labels = {
#标签,自定义标签
'sin':'sn号', 'u_count':'u数范围', } error_messages = {
#自定义错误信息
'idc':{
'required':'idc机房不能为空(请选择机房)', },} #localized_fields = ('birth_date',) #本地化,例如你取出数据库的时间,会根据setting中的配置
#转化成本地时间,如果localized_fields = '__all__' 所有的字段豆浆本地化

views中的大致操作:

obj2 = obj1(request.POST) #obj为你的modelform
if obj2.is_valid():
print('SSSSSS2')
obj2.save() else:
res2 = obj2.errors.as_data()
print(res2)
'''{'hostname': [ValidationError(['This field is required.'])], 'u_count': [ValidationError(['This field is required.'])], 'idc': [ValidationError(['idc机房不能为空(请选择机房)'])], 'cabinet': [ValidationError(['This field is required.'])], 'bussins': [ValidationError(['This field is required.'])], 'contact': [ValidationError(['This field is required.'])]}'''
#as_data出来是一个类似列表的形式,可以进行操作

NON_FIELD_ERRORS字段

在表单字段级或表单元级定义的错误消息总是优先于模型字段级别定义的错误消息。

通过在ModelForm的内部元类的errormessages词典中添加nonfielderrors键来覆盖由模型验证所引起的错误的错误消息:

from django.forms import ModelForm
from django.core.exceptions import NON_FIELD_ERRORS class ArticleForm(ModelForm):
class Meta:
error_messages = {
NON_FIELD_ERRORS: {
'unique_together': "%(model_name)s's %(field_labels)s are not unique.",
}
}

save()方法:

有两种情况:如果提供了instance关键字会进行更新操作,如果没有则会进行创建操作。

>>> from myapp.models import Article
>>> from myapp.forms import ArticleForm # Create a form instance from POST data.
>>> f = ArticleForm(request.POST) #创建
# Save a new Article object from the form's data.
>>> new_article = f.save() #更新
# Create a form to edit an existing Article, but use
# POST data to populate the form.
>>> a = Article.objects.get(pk=1)
>>> f = ArticleForm(request.POST, instance=a)
>>> f.save()

save() 中的commit字段()

这个字段很有用,他可以让你保存你save()的对象,先不必写入数据库,你可以先对他进行更改,添加属性,然后在存入数据库。

官方解释:

save()方法接受一个可选的提交关键字参数,它接受True或False。如果您用commit=False调用save(),那么它将返回尚未保存到数据库的对象。在这种情况下,由您在生成的模型实例上调用save()。如果您想在保存对象之前对其进行定制处理,或者如果您想要使用一个专门的模型保存选项,那么这是非常有用的。默认情况下save(commit=True)。

save(commit=False)实例:

# Create a form instance with POST data.
>>> a = Author()
>>> f = AuthorForm(request.POST, instance=a) # Create and save the new author instance. There's no need to do anything else.
>>> new_author = f.save()

save_m2m()方法:

save(commit=False)在处理复杂的多对多关系不好使

这个方法在满足以下条件的时候使用:

1.多对多关系

2.你需要添加额外的属性

3.save(commit=False)

# Create a form instance with POST data.
>>> f = AuthorForm(request.POST) # Create, but don't save the new author instance.
>>> new_author = f.save(commit=False) # Modify the author in some way.
#添加额外的属性
>>> new_author.some_field = 'some_value' # Save the new instance.
>>> new_author.save() # Now, save the many-to-many data for the form.
>>> f.save_m2m()

大致的思路,以及小坑

在写这个信息处理的时候,分为查询(包括修改),和添加操作,不在一个界面上,都需要进行验证,所以都使用AddAsset这个modelform进行验证,然而前端传过来的数据,只传过来修改的数据了,有的数据为空,所以有又回到前端,把所有数据包括没改的也发过来了。(找了好一会。。)

model.form使用,配合form的钩子的更多相关文章

  1. {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm

    Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...

  2. day75 form 组件(对form表单进行输入值校验的一种方式)

    我们的组件是什么呢 select distinct(id,title,price) from book ORM: model.py class Book(): title=model.CharFiel ...

  3. 高效开发之SASS篇 灵异留白事件——图片下方无故留白 你会用::before、::after吗 link 与 @import之对比 学习前端前必知的——HTTP协议详解 深入了解——CSS3新增属性 菜鸟进阶——grunt $(#form :input)与$(#form input)的区别

    高效开发之SASS篇   作为通往前端大神之路的普通的一只学鸟,最近接触了一样稍微高逼格一点的神器,特与大家分享~ 他是谁? 作为前端开发人员,你肯定对css很熟悉,但是你知道css可以自定义吗?大家 ...

  4. 使用Form Builder创建Form具体步骤

    使用Oracle Form Builder创建Form具体步骤 (Data Source为Table) 说明:当Block使用的Data Source为Table时,Form会自动Insert,Upd ...

  5. 关于Form.Close跟Form.Dispose

    我们在Winform开发的时候,使用From.Show来显示窗口,使用Form.Close来关闭窗口.熟悉Winform开发的想必对这些非常熟悉.但是Form类型实现了IDisposable接口,那我 ...

  6. 知道Form.Show()和Form.ShowDialog()的区别吗

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:知道Form.Show()和Form.ShowDialog()的区别吗.

  7. form.Show()和form.ShowDialog()的区别、新建一个form和MessageBox.Show()的常见用法

    一:form.Show()和form.ShowDialog()的区别 a. 任何窗体(派生于基类Form的类),都可以以两种方式进行显示. //非模式窗体From qform=new Form();q ...

  8. Form.Close跟Form.Dispose

    关于Form.Close跟Form.Dispose   我们在Winform开发的时候,使用From.Show来显示窗口,使用Form.Close来关闭窗口.熟悉Winform开发的想必对这些非常熟悉 ...

  9. $(#form :input)与$(#form input)的区别

    相信大家都很奇怪这两者的区别 我从两个方面简单介绍下 1. $("form :input") 返回form中的所有表单对象,包括textarea.select.button等    ...

随机推荐

  1. 蓝牙协议分析(5)_BLE广播通信相关的技术分析

    1. 前言 大家都知道,相比传统蓝牙,蓝牙低功耗(BLE)最大的突破就是加大了对广播通信(Advertising)的支持和利用.关于广播通信,通过“玩转BLE(1)_Eddystone beacon” ...

  2. shell脚本监测DNS链接状态给传给zabbix值

    #!/bin/sh time_out=0 querygt3s=0 i=1 while [[ $i -le 15 ]] do i=`expr $i + 1` sleep 2 while read lin ...

  3. MVVM设计模式加RAC响应式编程

    一:为什么要用MVVM? 为什么要用MVVM?只是因为它不会让我时常懵逼. 每次做完项目过后,都会被自己庞大的ViewController代码吓坏,不管是什么网络请求.networking data ...

  4. jQuery-2.DOM---节点的删除

    DOM节点删除之empty()的基本用法 要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题,这里我们开仔细了解下empty方法 empty 顾名思义,清空方法,但是 ...

  5. 《Linux内核原理与分析》第四周作业

    课本:第3章 MenuOS的构造 内容总结 计算机的"三大法宝" 存储程序计算机 函数调用堆栈 中断 操作系统的"两把宝剑" 中断上下文切换:保存现场和恢复现场 ...

  6. python的高阶函数式编程

    首先   函数式编程≠函数编程,就跟计算机≠计算,因为计算机基于硬件,计算基于算法,所以函数式编程是倾向于算法. 高阶函数定义: 一个函数接受的这个参数,而这个参数也是一个函数,称之为高阶函数 例如: ...

  7. tmpfs临时文件系统,是一种基于内存的文件系统

    在Linux系统内存中的虚拟磁盘映射,可以理解为使用物理内存当做磁盘,利用这种文件系统,可以有效提高在高并发场景下的磁盘读写,但是重启后数据会丢失. 1.查看tmpfs路径 (系统默认开启,大小约为物 ...

  8. PythonStudy——阶段总结

    每个数据类型的最大特点是什么? (1)int整型:用于存放整形对象,是不可变类型.若将一个整数赋值给一个变量名,python可自动将其设置为int型. 例如:age = 30 这里的age对象的typ ...

  9. live555 交叉编译移植到海思开发板

    本文章参考了.http://blog.csdn.net/lawishere/article/details/8182952,写了hi3518的配置说明.特此感谢 https://blog.csdn.n ...

  10. Optaplanner - 从探究示例中的hello world,初步认识规划引擎的运行步骤。

    上一篇我们成功以把Opotaplanner规划引擎下载回来,并把它的示例运行起来,简单解析了一下它的Cloud balance示例.这一篇我们这些示例的源代码导入到Eclipse中,看看它在后台是怎么 ...