Python 统一动态创建多个model对应的modelForm类(type()函数)

Posted yoyo008

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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_django_models模块

python新手关于from..import..as的用法?

Django在使用models生成数据库表时报错: __init__() missing 1 required positional argument: 'on_delete'

Python不支持函数重载

django model 条件过滤 queryset.filter(**condtions) 用法

ORM