Python 统一动态创建多个model对应的modelForm类(type()函数)
一、ModelForm的用法
ModelForm对用户提交的数据有验证功能,但比Form要简单的多
from django.forms import ModelForm # 导入ModelFormclasscustomerModelForm(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函数的写法很简 ...
随机推荐
- 一种保持顺序的Properties
其实properties有没有顺序都一样 程序都能正常运行 但看着就比较闹心 所以网上找了找 还真有人给了个例子实现读Property的有序 但是删除某些属性之后 写入又有问题 会异常 后来重写了一下 ...
- javascript string对象方法replace
最简单的replace用法是: var str = 'aaaaa9876b0000'; str.replace(/a/g,'A'); 有时候我们希望只是在匹配的位置添加特定的字符: var str = ...
- BZOJ3522 POI2014HOT-Hotels(树形dp)
分两种情况.三点两两lca相同:在三点的lca处对其统计即可,显然其离lca距离应相同:某点在另两点lca的子树外部:对每个点统计出与其距离x的点有多少个即可. 可以长链剖分做到线性,当然不会. #i ...
- [Leetcode] Path Sum II路径和
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- React & Redux 的一些基本知识点
一.React.createClass 跟 React.Component 的区别在于后者使用了ES6的语法,用constructor构造器来构造默认的属性和状态. 1. React.createCl ...
- makefile使用笔记(一)入门
By francis_hao Mar 2,2017 makefile makefile一个很简单的例子如下,该实例完成在执行make时,将main.c编译成可执行文件main的功能. 各项的含义 ...
- n元线性方程非负整数解的个数问题
设方程x1+x2+x3+...+xn = m(m是常数) 这个方程的非负整数解的个数有(m+n-1)!/((n-1)!m!),也就是C(n+m-1,m). 具体解释就是m个1和n-1个0做重集的全排列 ...
- HDU3605:Escape(状态压缩+最大流)
Escape Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- Eclipse CDT 调用printf/cout 控制台(console)无输出
转摘自:http://blog.csdn.net/dj0379/article/details/6940836 症状描述: 用Eclipse调试程序,执行printf和cout函数,但是console ...
- css和javascript中图片路径的不同
之前在写前端代码时,在图片路径的设置那里经常会遇到一个问题.比方说,我 (1)在根目录下面新建了个"images"文夹,里面放了张图片top.gif (2)在根目录下另外新建了两个 ...