Python

如何动态的生成 ModelForm

2018-12-22  本文已影响0人  摘花是个好习惯

在项目中新建 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', <django.forms.fields.CharField object at 0x000001385625DA90>)]),
        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 的两个参数

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 判断字段是否为空,给不能为空的添加<b>标签

<form class="form-horizontal" method="POST">

    {% for field in form_obj %}
         <div class="form-group">
              <div class="col-md-8" style="font-weight: normal">
                   <div class="col-md-2 col-md-offset-1" >
                        {% if field.field.required %}
                             <b>{{ field.label }}</b>
                        {% else %}
                             {{ field.label }}
                        {% endif %}
                   </div>
                   <div class="col-md-6">
                      {{ field }}
                  </div>
             </div>
         </div>
     {% endfor %}
     <button type="submit" class="btn btn-success pull-right" style="margin-bottom: 50px">save</button>
</form>
上一篇 下一篇

猜你喜欢

热点阅读