一、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()函数)的更多相关文章

  1. python中动态创建类

    class Foo(Bar): pass Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__创建一个名字为Foo的类对象(我说的是类对象,请紧 ...

  2. spring 动态创建数据源

    项目需求如下,公司对外提供服务,公司本身有个主库,另外公司会为每个新客户创建一个数据库,客户的数据库地址,用户名,密码,都保存在主数据库中.由于不断有新的客户加入,所以要求,项目根据主数据库中的信息, ...

  3. 《深入浅出MFC》系列之动态创建

    /*************************************************************************************************** ...

  4. MFC六大核心机制之三:动态创建

    MFC中很多地方都使用了动态创建技术.动态创建就是在程序运行时创建指定类的对象.例如MFC的单文档程序中,文档模板类的对象就动态创建了框架窗口对象.文档对象和视图对象.动态创建技术对于希望了解MFC底 ...

  5. 动态创建TeeChart的简便方法

    最近在项目中使用Teechart ocx版本替换了labview的老版本控件,显示效果和效率均有提高,但是却遇到多线程下报access violation的问题. 翻遍大小论坛,最后在官网论坛找到相同 ...

  6. 面向对象相关概念与在python中的面向对象知识(魔法方法+反射+元类+鸭子类型)

    面向对象知识 封装 封装的原理是,其成员变量代表对象的属性,方法代表这个对象的动作真正的封装是,经过深入的思考,做出良好的抽象(设计属性时用到),给出“完整且最小”的接口,并使得内部细节可以对外透明( ...

  7. Python中使用type、metaclass动态创建方法和属性

    1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ...

  8. sqlalchemy根据表名动态创建model类

    作用如题,直接上代码吧,另外还支持 copy一张表的表结构,新建表并获得model对象 # coding: utf-8 import traceback from sqlalchemy import ...

  9. Python 动态创建函数【转】

    知乎上也有相似的问题 偶然碰到一个问题,初想是通过动态创建Python函数的方式来解决,于是调研了动态创建Python函数的方法. 定义lambda函数 在Python中定义lambda函数的写法很简 ...

随机推荐

  1. Linux中安装apache

    一.前言 安装的背景就是公司项目要用,自己在linux安装软件不多,过程比较曲折,需要记录一下(最近几篇博客好像都会有这种高大上的背景)~先说下笔者安装环境以及相关软件版本: 操作系统:RedHat ...

  2. 每个分组函数相当于一个for循环 将集合的变量不断遍历

    每个分组函数相当于一个for循环  将集合的变量不断遍历

  3. 【bzoj3813】奇数国 线段树

    题目描述 给出一个长度为n的序列,每个数都可以由前60个质数的乘积表示,初始每个数都是3.支持两种操作:(1)修改一个数 (2)查询一段区间内所有数的乘积的欧拉函数值模19961993. 输入 第一行 ...

  4. MySQL 创建一个简单的成绩管理系统

    操作过程使用实验楼. 首先是创建一个数据库studentsystem,使用语句是: CREATE DATABASE studentsystem;  查看创建好的数据库的命令还是SHOW DATABAS ...

  5. 【NOIP模拟赛】天神下凡 动态开点线段树

    这些圆一定是在同一水平面上的,由于他们没有相交,因此我们发现他们每个人与外界关系可以分为,1.存在并圈圈 2.存在圈圈并被割,因此我们把所有的圆都加1,把被割的在加1,就可以啦,因此我们开一个线段树, ...

  6. Could not resolve com.android.support:multidex:1.0.2

    http://blog.csdn.net/goodlixueyong/article/details/50992835

  7. 通用adapter

    http://blog.csdn.net/lmj623565791/article/details/38902805/

  8. c++编辑器下载地址

    https://msdn.itellyou.cn/ 输入上述地址选中下图所示的按钮:

  9. HDU2057

    http://acm.hdu.edu.cn/showproblem.php?pid=2057 涉及到16进制内的加法,可以用%I64x直接来处理,要注意到16进制中负数是用补码来表示的.一个比较困惑的 ...

  10. bzoj3779: 重组病毒 link-cut-tree

    题目传送门 这道题看了做了个神转换.....推荐个博客给各位大爷看看吧神犇传送门 代码敲了半天....题目也读了半天 线段树维护的东西很容易和lct混在一起 调了调能过也是很开心啊 运气比较好吧233 ...