第七章、動態modelform功能實現
7.1.動態modelform的實現
(1)給第一列添加一個a標簽
kingadmintag.py

(2)kingadmin/urls.py
urlpatterns = [ #修改頁面 url(r'^(\w+)/(\w+)/(\d+)/change/$', views.table_obj_change,name='table_obj_change'), ]
(3)kingamdin/views.py
@login_required def table_obj_change(request,app_name,model_name,obj_id): '''kingadmin 數據修改頁''' return render(request,'kingadmin/table_obj_change.html')
(4)table_obj_change.html
{#kingadmin/templates/kingadmin/table_obj_change.html#} {% extends 'kingadmin/index.html' %} {% load kingadmin_tags %} {% block right-content-container %} <h2 class="page-header">app</h2> <div> change </div> {% endblock %}

(5)動態modelform生成
生成類的兩種方式,第二種相當於動態生成的

舉例:

新建kingadmin/form_handle.py
# kingadmin/formhandle.py from django.forms import ModelForm def create_dynamic_model_form(admin_class): '''動態生成modelform''' class Meta: model = admin_class.model fields = "__all__" #動態生成ModelForm dynamic_form = type("DynamicModelForm",(ModelForm,),{'Meta':Meta}) return dynamic_form
kingadmin/views.py
@login_required def table_obj_change(request,app_name,model_name,obj_id): '''kingadmin 數據修改頁''' admin_class = site.enable_admins[app_name][model_name] model_form = form_handle.create_dynamic_model_form(admin_class) # 實例化 form_obj = model_form() return render(request,'kingadmin/table_obj_change.html',locals())
table_obj_change.html

現在動態ModelForm的功能就實現了


7.2.動態ModelForm增加自定義樣式

靜態ModelForm增加自定樣式的寫法
crm/form.py
# crm/form.py from django.forms import ModelForm from crm import models class CustomerForm(ModelForm): class Meta: model = models.CustomerInfo fields = "__all__" #django是通過“__new__”方法,找到ModelForm里面的每個字段的,然后循環出每個字段添加自定義樣式 def __new__(cls, *args, **kwargs): #cls.base_fields是一個元祖,里面是 所有的 【(字段名,字段的對象),(),()】 for field_name in cls.base_fields: filed_obj = cls.base_fields[field_name] #添加屬性 filed_obj.widget.attrs.update({'class':'form-control'}) return ModelForm.__new__(cls)
動態ModelForm增加自定義樣式
(1)kingadmin/form_handle.py
# kingadmin/formhandle.py from django.forms import ModelForm def create_dynamic_model_form(admin_class): '''動態生成modelform''' class Meta: model = admin_class.model fields = "__all__" # django是通過“__new__”方法,找到ModelForm里面的每個字段的,然后循環出每個字段添加自定義樣式 def __new__(cls, *args, **kwargs): # cls.base_fields是一個元祖,里面是 所有的 【(字段名,字段的對象),(),()】 for field_name in cls.base_fields: #每個字段的對象 filed_obj = cls.base_fields[field_name] # 添加屬性 filed_obj.widget.attrs.update({'class': 'form-control'}) return ModelForm.__new__(cls) #動態生成ModelForm dynamic_form = type("DynamicModelForm",(ModelForm,),{'Meta':Meta,'__new__':__new__}) return dynamic_form
可以打印cls.base_fields看下
OrderedDict([('name', <django.forms.fields.CharField object at 0x0000000004761D68>), ('url_type', <django.forms.fields.TypedChoiceField object at 0x0000000004772128>), ('url_name', <django.forms.fields.CharField object at 0x0000000004772240>)])
(2)table_obj_list.html
{#kingadmin/templates/kingadmin/table_obj_change.html#} {% extends 'kingadmin/index.html' %} {% load kingadmin_tags %} {% block right-content-container %} <h2 class="page-header">app</h2> <form class="form-horizontal"> {% for field in form_obj %} <div class="form-group"> <label class="col-sm-2 control-label">{{ field.label }}</label> <div class="col-sm-10"> {{ field }} </div> </div> {% endfor %} </form> {% endblock %}
效果:

7.3.實現任意表的增加和修改功能
現在的表單是添加的表單,如何變成是修改的表單呢?
(1)views.py

(2)table_obj_change.html
顯示表名和修改的字段名

添加一個按鈕

效果:

修改功能實現
kingadmin/views.py
def table_obj_change(request,app_name,model_name,obj_id): '''kingadmin 數據修改頁''' admin_class = site.enable_admins[app_name][model_name] model_form = form_handle.create_dynamic_model_form(admin_class) #讓表單變成是修改的表單 obj = admin_class.model.objects.get(id=obj_id) #修改 if request.method == 'GET': form_obj = model_form(instance=obj) elif request.method == 'POST': form_obj = model_form(instance=obj,data=request.POST) if form_obj.is_valid(): form_obj.save() #修改后跳轉到的頁面 return redirect("/kingadmin/%s/%s/"%(app_name,model_name)) return render(request,'kingadmin/table_obj_change.html',locals())
table_obj_list.html添加錯誤提示

添加功能實現
(1)kingadmin/url.py
#增加 url(r'^(\w+)/(\w+)/add/$', views.table_obj_add,name='table_obj_add'),
(2)kingadmin/views.py
@login_required def table_obj_add(request,app_name,model_name): '''kingadmin 數據添加''' admin_class = site.enable_admins[app_name][model_name] model_form = form_handle.create_dynamic_model_form(admin_class) if request.method == 'GET': form_obj = model_form() elif request.method == 'POST': form_obj = model_form(data=request.POST) if form_obj.is_valid(): form_obj.save() #跳轉到的頁面 return redirect("/kingadmin/%s/%s/"%(app_name,model_name)) return render(request, 'kingadmin/table_obj_add.html', locals())
(3)前端頁面
因為添加和修改的表單是一樣的,所以單獨新建table_obj_change_component.html(放form表單),然后chang和add 的html直接include
table_obj_change_component.html
{#kingadmin/templates/kingadmin/table_obj_change_component.html#} <form class="form-horizontal" method="post"> {% csrf_token %} {{ form_obj.errors }} {% for field in form_obj %} <div class="form-group"> <label class="col-sm-2 control-label">{{ field.label }}</label> <div class="col-sm-10"> {{ field }} <span style="color: red;">{{ field.errors.0 }}</span> </div> </div> {% endfor %} <div class="form-group"> <div class="col-sm-offset-11 col-sm-10"> <button type="submit" class="btn btn-info">Save</button> </div> </div> </form>
table_obj_change.html
{#kingadmin/templates/kingadmin/table_obj_change.html#} {% extends 'kingadmin/index.html' %} {% load kingadmin_tags %} {% block right-content-container %} <h2 class="page-header">{% get_model_name admin_class %}</h2> <h4 class="page-header">修改{{ form_obj.instance }}</h4> <div> change {% include 'kingadmin/table_obj_change_component.html' %} </div> {% endblock %}
table_obj_add.html
{#kingadmin/templates/kingadmin/table_obj_add.html#} {% extends 'kingadmin/index.html' %} {% load kingadmin_tags %} {% block right-content-container %} <h2 class="page-header">{% get_model_name admin_class %}</h2> <h4 class="page-header">添加{% get_model_name admin_class %}</h4> <div> add {% include 'kingadmin/table_obj_change_component.html' %} </div> {% endblock %}
(4)新增加的數據應該顯示在最前面

