pop功能模仿Django-Admin中添加页面的pop功能

pop功能需要实现的功能和问题

1 如何在一对多和多对多字段后渲染 +
2 +对应的跳转路径是什么
3 保存添加记录同时,将原页面的对应的下拉菜单中添加该记录

具体实现(只在添加页面实现功能)添加页面代码逻辑(包含pop功能):

此处请参考ModleForm相关内容

def add(self, request): #ModelFormDemo等同于得到了DemoModelForm这个类 ModelFormDemo = self.get_modelForm() #实例化出来一个form对象 form = ModelFormDemo() #通过循环判断没有个字段类是否是判断form对象是否是一对多或多对多,并做相应处理 for bfield in form: from django.forms.models import ModelChoiceField #ModelMultipleChoiceField继承ModelChoiceField,因此一对多和多对多都是ModelChoiceField #如果当前对象是一对多或多对多 if isinstance(bfield.field, ModelChoiceField): #添加一个属性,用于在模板中判断是否渲染页面时加上加号 bfield.is_pop = True # print("====>",bfield.field.queryset.model) # == == > < class 'app01.models.Publish'> # == == > < class 'app01.models.Author'> #获取app名字和关联表的名称 related_model_name = bfield.field.queryset.model._meta.model_name related_app_lable = bfield.field.queryset.model._meta.app_label #利用反向解析找到url _url = reverse("%s_%s_add" % (related_app_lable, related_model_name)) # print(_url) # / stark / app01 / publish / add / # / stark / app01 / author / add / #构建url值,这个值要传给模板用 bfield.url = _url+"?pop_res_id=id_%s" %bfield.name #bfield.url == > / stark / app01 / author / add /?pop_res_id = id_authors # 如果收到POST请求则修改数据 # 这里有两种情况,一种是通过pop添加数据,此时url带有pop_res_id,一种是在查看页面点添加,url里是没有pop_res_id的 if request.method == "POST": #将request.POST放到form中进行校验 form = ModelFormDemo(request.POST) if form.is_valid(): obj = form.save() # print("obj==>", obj) #obj==> Django 第二版 # print("type==>", type(obj)) #type==> <class 'app01.models.Book'> #获取(pop功能提交的post请求时)url中的pop_res_id值 pop_res_id = request.GET.get("pop_res_id") #如果此处有值就将数据返回给pop.html页面 if pop_res_id: res = {"pk": obj.pk, "text": str(obj), "pop_res_id": pop_res_id} return render(request, "pop.html", {"res": res}) else: #如果此次无值则直接跳转到相应页面 return redirect(self.get_list_url()) # return redirect("/stark/app01/book/") return render(request, "add.html", locals())添加页面渲染(form.html)

<div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form action="" method="post" novalidate> {% csrf_token %} {% for field in form %} <div class="form-group"> <label for="">{{ field.label }}</label> {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span> <!-- 下面判断field是否有is_pop属性为True --> <!-- 有的话就在输入框后面添加一个加号,并绑定pop事件 --> {% if field.is_pop %} <a onclick="pop('{{ field.url }}')" ><span >+</span></a> {% endif %} </div> {% endfor %} <input type="submit" class="btn btn-default"> </form> </div> </div></div><!-- 点击加号就触发pop函数 --><script> function pop(url) { // 打开一个独立的添加窗口 window.open(url, "", "width=600,height=400,top=100,left=100") }</script>pop页面

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title></head><body><script> // 触发父页面的pop_response函数,并且把参数传过去 window.opener.pop_response('{{ res.pk }}', '{{ res.text }}', '{{ res.pop_res_id }}'); // 之后立即关闭这个页面 window.close()</script></body></html>add页面body示例代码(是pop页面的父页面)

<body><h4>添加数据</h4>{% include 'form.html' %}<script> function pop_response(pk, text, id) { // 选择哪个select标签 // option的文本值和value值 // 生成一个空的option标签 var $option=$('<option>'); // 往option标签中添加内容 $option.html(text); $option.val(pk); $option.attr("selected", "selected"); // 按id找位置,将标签添加进去 $("#"+id).append($option) }</script></body>