Python 统一动态创建多个model对应的modelForm类(type()函数)
一、ModelForm的用法
ModelForm对用户提交的数据有验证功能,但比Form要简单的多
from
django.forms
import
ModelForm
# 导入ModelFormclass
customerModelForm(ModelForm):
class
Meta:
model
=
models.UserInfo
fields
=
"__all__"
labels
=
{
'name'
:
'用户名'
,
'password'
:
'密码'
,
'qq'
:
'qq号'
,
'微信'
:
'微信号'
,
'roles'
:
'角色'
}
说明:
1.model:对应得表名
2.fields:选择字段列表,'__all__'是选择所有字段
3.exclude:排除字段列表
4.widgets:插件列表
5.labels:前端显示字段名
6.error_messages:自定义错误提示
7.localized_field:本地化,如:根据不同时区显示数据
除了这些参数,ModelForm和Form一样可以定义局部钩子和全局钩子
2.实例化表单对象,传入模板,同Form
model_form
=
customerModelForm()return
render(request,
"index.html"
,{
"model_form"
:model_form})
3、前端通过传递的model_form展示
<div class="row">
{{ model_form.errors }}
<form class="form-horizontal" method="post" >
{% csrf_token %}
{% for field in model_form %}
<div class="form-group">
<label class="col-sm-2 " style="font-weight: normal">
{% if field.field.required %}
<b> {{ field.label }} (*必填项) </b>
{% else %}
{{ field.label }}
{% endif %}
</label>
<div class="col-sm-10">
<span style="color: red;">{{ field.errors }}</span>
{{ field }}
</div>
</div>
{% endfor %}
</form>
</div>
4、form提交后,后端view通过以下方式,验证提交的表单
model_form
=
customerModelForm(request.POST)
if
model_form.is_valid():
model_form.save()
5.如果是修改记录,则需要传入记录对象
obj = customerModel.objects.get(id=obj_id) #查到原来的值
model_form
=
customerModelForm(instance
=
user_obj) #传入值
model_form
=
customerModelForm(request.POST, instance
=
obj) #将原来的值生成新值
if
model_form.is_valid():
model_form.save()
|
二、有多个Model,不想要每个model写一个ModelForm的,采用动态生成ModelForm类的方法
A、动态生成类的函数:type('classname',(object,),dict(funname=fun))
参数:
1、class的名称,字符串形式;
2、继承的父类集合,注意Python支持多重继承,如果只有一个父类,注意tuple的单元素写法;
3、class的方法名称与函数绑定,这里我们把函数fun绑定到方法名funname上,可以采用:
setattr(classname,"funname",fun)方式替代 例子:
def CreateModelForm(request,admin_obj):
class Meta:
model = admin_obj.model
fields = "__all__" def __new__(cls, *args, **kwargs):
for field_name,field_obj in cls.base_fields.items():
field_obj.widget.attrs['class'] = 'form-control'
if field_name in admin_obj.readonly_fields:
field_obj.widget.attrs['disabled'] = True #在后台不能通过这种方式修改外键对应的字段,比如consultant
return forms.ModelForm.__new__(cls) def default_clean(self):
print("cleaned data:",self.cleaned_data) dynamic_model_form = type("DynamicModelForm",(forms.ModelForm,), {"Meta":Meta})
setattr(dynamic_model_form,"__new__",__new__)
setattr(dynamic_model_form,"clean",default_clean)
return dynamic_model_form 上述例子就可以根据需求动态生成dynamic_model_form了,需要使用的时候调用CreateModelForm函数即可
model_form = forms.CreateModelForm(request,admin_obj=admin_obj)
Python 统一动态创建多个model对应的modelForm类(type()函数)的更多相关文章
- python中动态创建类
class Foo(Bar): pass Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧 ...
- spring 动态创建数据源
项目需求如下,公司对外提供服务,公司本身有个主库,另外公司会为每个新客户创建一个数据库,客户的数据库地址,用户名,密码,都保存在主数据库中.由于不断有新的客户加入,所以要求,项目根据主数据库中的信息, ...
- 《深入浅出MFC》系列之动态创建
/*************************************************************************************************** ...
- MFC六大核心机制之三:动态创建
MFC中很多地方都使用了动态创建技术.动态创建就是在程序运行时创建指定类的对象.例如MFC的单文档程序中,文档模板类的对象就动态创建了框架窗口对象.文档对象和视图对象.动态创建技术对于希望了解MFC底 ...
- 动态创建TeeChart的简便方法
最近在项目中使用Teechart ocx版本替换了labview的老版本控件,显示效果和效率均有提高,但是却遇到多线程下报access violation的问题. 翻遍大小论坛,最后在官网论坛找到相同 ...
- 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)
面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...
- Python中使用type、metaclass动态创建方法和属性
1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ...
- sqlalchemy根据表名动态创建model类
作用如题,直接上代码吧,另外还支持 copy一张表的表结构,新建表并获得model对象 # coding: utf-8 import traceback from sqlalchemy import ...
- Python 动态创建函数【转】
知乎上也有相似的问题 偶然碰到一个问题,初想是通过动态创建Python函数的方式来解决,于是调研了动态创建Python函数的方法. 定义lambda函数 在Python中定义lambda函数的写法很简 ...
随机推荐
- java生成唯一的id编号
GUID是一个128位长的数字,一般用16进制表示.算法的核心思想是结合机器的网卡.当地时间.一个随即数来生成GUID.从理论上讲,如果一台机器每秒产生10000000个GUID,则可以保证(概率意义 ...
- ES 1.7安装ik分词elasticsearch-analysis-ik-1.2.5
IK简介 https://www.cnblogs.com/yjf512/p/4789239.html https://www.cnblogs.com/xing901022/p/5910139.html ...
- Beats数据采集
Beats数据采集 Beats是elastic公司的一款轻量级数据采集产品,它包含了几个子产品: packetbeat(用于监控网络流量). filebeat(用于监听日志数据,可以替代logstas ...
- 【bzoj1257】[CQOI2007]余数之和sum 数论
题目描述 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的余数.例如j(5, 3)=3 m ...
- IE6,7,8支持css圆角
我们知道Webkit内核的浏览器支持-webkit-border-radius: 10px;属性(10px是圆角半径),可以直接解析出圆角;Firefox浏览器支持-moz-border-radius ...
- hdu 3172 Virtual Friends (并查集)
Virtual Friends Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- 使用def文件简化dll导出
原文链接地址:http://www.cnblogs.com/TianFang/archive/2013/05/04/3059073.html 在C++中,我们可以通过 __declspec(dllex ...
- 用JQuery的$.getJSON发起跨域Ajax请求
jQuery中常用getJSON来调用并获取远程的JSON字符串,将其转换为JSON对象,如果成功,则执行回调函数.原型如下: jQuery.getJSON( url, [data], [callba ...
- MySQL使用笔记(七)排序和限制数据记录查询
By francis_hao Dec 17,2016 排序数据记录查询 排序是指将筛选出符合条件的数据进行有序排放,有升序(ASC(默认))方式和降序(DESC)方式. mysql> se ...
- Windows下查看某个端口被哪个服务占用
1.查看某个端口是否被占用 打开命令行,输入:netstat -ano | findstr "3306" 2.查看端口被哪个服务占用 tasklist | findstr “PID ...