如何动态的生成 ModelForm

在项目中新建 forms.py文件

from django import forms

def create_model_form(request,admin_class):
    '''动态生成Model Form'''

    # 修改样式
    def __new__(cls, *args, **kwargs):
        #print(cls.base_fields)     OrderedDict([('name', )]),
        for field_name,field_obj in cls.base_fields.items():
            # 根据 cls.base_field 的特性给每个字段加上样式
            cls.base_fields[field_name].widget.attrs['class'] = 'form-control'

        return forms.ModelForm.__new__(cls)

    class Meta:
        model = admin_class.model        # 通过admin_class动态获取model
        # fields = ('name', 'qq')        # 可以获取指定字段
        # age = forms.IntegerField()     # 还可以添加字段
        fields = '__all__'               # '__all__'获取所有字段

    attrs = {'Meta':Meta}

    _model_form_class = type("DynamicModelForm", (forms.ModelForm,), attrs)     # 第一个参数是类名,第二个参数是元组,填写父类,最后必须添加逗号,
                                                                                #  第三个参数字典形式的Meta类
    # 方法一定要 setattr  
    setattr(_model_form_class,'__new__',__new__)
    return _model_form_class    # 返回的是一个类

在视图函数中调用 forms.create_model_form()

model_form_class 的两个参数

  • instance : 将表对象实例到前端,使用这个参数后前端的输入框会默认填充修改前的值
  • request.POST:提交表单后,如果不传入request.POST 会变成新建表对象的效果
def table_obj_change(request,app_name,table_name,obj_id):
    admin_class = king_admin.enabled_admins[app_name][table_name]

    model_form_class = forms.create_model_form(request, admin_class)
    
    # 根据后端传入的id获得要修改的表对象
    obj = admin_class.model.objects.get(id=obj_id)
    
    # 表单提交后重新调用 create_model_form(),并且把request.POST传进去
    if request.method == 'POST':
        form_obj = model_form_class(request.POST, instance=obj)

        # 前端填写的数据没有异常就保存
        if form_obj.is_valid():
            # ModelForm的方式可以直接 save 保存
            form_obj.save()
            # 通过反转回到 table_name 表
            return redirect(reverse('table_obj',kwargs={'app_name':app_name,'table_name':table_name}))
    else:
        form_obj = model_form_class(instance=obj)

    return render(request, 'king_admin/table_obj_change.html', {'form_obj':form_obj})

前端

required : 判断字段是否能为空,不能为空为True

实现字段的 label 根据非空显示字体粗细的方法:

由于django的表单方法会默认给 字段的 label 加粗,所以给 div 一个 style="font-weight: normal",再循环表单对象, 使用 field.required 判断字段是否为空,给不能为空的添加标签

{% for field in form_obj %}
{% if field.field.required %} {{ field.label }} {% else %} {{ field.label }} {% endif %}
{{ field }}
{% endfor %}

你可能感兴趣的:(如何动态的生成 ModelForm)