Django 之stark 组件的pop_up功能
Django 之 ModelForm表单的类的分析 >>点我
html 之DOM open()方法 >>点我
1.增加和编辑页面
form=ModelFormClass() for bound_field in form: # form组件下的每一个字段信息对象:bound_field # print("field",type(bound_field)) # print(bound_field.name,bound_field.field) if isinstance(bound_field.field, ModelChoiceField): bound_field.is_pop = True print(bound_field.field.queryset.model)
#queryset.model的方法能够得到这个model对象 app_label = bound_field.field.queryset.model._meta.app_label model_name = bound_field.field.queryset.model._meta.model_name
_url = "%s_%s_add" % (app_label, model_name) #将url反解出来 并在拼接上?pop_id=id_publishs的这种类型以便于最后一步将数据返回给父页面的标签中去 bound_field.url = reverse(_url) + "?pop_id=id_%s" % bound_field.name #将form对象返回给了form.html return {"form":form}
2.form.html中的代码
#form.html接受传过来的form对象,将内容渲染出来 <form action="" method="post" novalidate> {% for field in form %} <div class="form-group" style="position: relative"> <label for="">{{ field.label }}</label> <div class="input_style"> {{ field }} <span class="error pull-right">{{ field.errors.0 }}</span> </div> #判断是否有is_pop字段,有的话证明他是一个一对多,多对多字段,给他加上一个a标签并在a标签中绑定事件 #点击触发pop事件,并将数据传给这个函数 {% if field.is_pop %} <a onclick="pop('{{ field.url }}')" style="position: absolute;top: 24px;right: -23px"
class="pop_btn">
<span class="pull-right" style="font-size: 22px;">+</span></a> {% endif %} </div> {% endfor %} <div class="form-group"> <p><input type="submit" class="btn btn-default" ></p> </div> </form> #页面中的script定义好的pop方法 <script> function pop(url){ #打开一个url为传入的url 的页面,‘’,页面的长宽位置设置如下 window.open(url,'','width=500,height=400,top=200,left=500') } </script>
3.弹出的添加框添加完数据点击提交之后,对post请求进行判断
myform=ModelForms(data=request.POST) if myform.is_valid(): new_obj=myform.save() list_url=self.get_list_url() # print('list_url===========',list_url,type(list_url)) #如果有pop_id 证明这是通过其他页面pop添加数据的 if request.GET.get('pop_id',0): #构建一个字典,用于存放新添加的内容的主键,名称,字段名称 最后一个pop_id对应的是应为原来的筛选表中 #的name字段为 name="id_publishs" 的类型的 data = {"pk": new_obj.pk, 'text': new_obj.__str__(),'pop_id':'%s'%request.GET.get('pop_id')} import json data = json.dumps(data) #将内容返回到中间表中去 print('这是新的data------------------',data) #接着走到stark/pop_resp.html页面并将data传给这个页面 return render(request,'stark/pop_resp.html',{"data":data}) #如果没有pop_id的话,则提交成功后返回显示list页面 else: return redirect(self.get_list_url())
(4) (子窗口页面)
页面功能,调用父页面的函数将数据传给父页面
调用函数功能完成之后关闭此页面
弹出页面的get请求:
返回添加页面
弹出页面的post请求:
<!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> <h3>这是POP response</h3> {{ data }} <script> {# 这是用pop打开添加页面完成添加功能后返回的页面 打开页面后自动完成的#} {# 在此页面中调用 opener.foo 即是在调用他的父页面pop函数功能 #} {# 并将数据传送给这个函数,为了避免将数据转意 用 |safe方法讲数据传过去 #} opener.foo('{{ data|safe }}'); {# 将此页面关闭#} window.close(); </script> </body> </html>
5 父页面中的foo 函数对传过来的数据进行处理
<script> #函数被子窗口页面触发,将数据写入到页面标签中去 function foo(res) { console.log(res); var res=JSON.parse(res);
#定义一个option标签 var ele_option=document.createElement("option");
#给标签写入内容 ele_option.value=res.pk;
ele_option.innerHTML=res.text;
#拼接成这样形式的标签<option selected="selected" value="6">沙河校区</option>
#标签的数据为被选中的形式 ele_option.selected="selected"; console.log(ele_option);
#找到标签位置,将数据添加进去 document.getElementById(res.pop_id).appendChild(ele_option) } </script>
def add_view(self, request): ModelForms = self.creat_modelform() from django.forms.boundfield import BoundField #引入modelChoiceField类 from django.forms.models import ModelChoiceField if request.method == "GET": myform = ModelForms() #实例化一个表单对象 boundField_list=[] for boundField in myform: # print(type(boundField),'这是文件的种类。。。。。。。。。。。。。。。。。。') # 通过打印实例化的myform对象中每一个字段对象的种类得知他的类型是<class 'django.forms.boundfield.BoundField'> #判断字段对象是不是ModelChoiceField类的,如果是的话,则证明他是一对多,多对多字段,是外键 能够关联到其他表 if isinstance(boundField.field,ModelChoiceField): #通过boundFiled的name属性,获取字段的名称 aa=self.model._meta.get_field(boundField.name) # print(aa,'aaa------------') #获取关联到字段的添加页面的url, 通过rel方法,获取所有外键关联的对象,的第一个, # 然后再通过_meta.model_name的方法来获取这个表的名称 to_add_url=aa.rel.to.objects.all().first()._meta.model_name #反向解析出url url=reverse('%s_%s_add'%(self.model._meta.app_label,to_add_url)) #然后给每个url中添加一个标志内容,如 ?pop_id=字段名,这个用于当在新页面添加完数据后将内容返回到添加的这个字段内部 # url=url+'?pop_id=%s'%(boundField.name) #将所有boundField放入列表中,并设置一个is_pop属性为True来判断是否要显示pop按钮 boundField_list.append({"bound_field":boundField,'is_pop':True,"url":url}) else: boundField_list.append({"bound_field": boundField, 'is_pop': False}) # print('boundField_list-----',boundField_list) # return HttpResponse('OOK') return render(request, 'stark/add.html', locals()) else: myform=ModelForms(data=request.POST) if myform.is_valid(): new_obj=myform.save() list_url=self.get_list_url() # print('list_url===========',list_url,type(list_url)) #如果有pop_id 证明这是通过其他页面pop添加数据的 if request.GET.get('pop_id',0): #构建一个字典,用于存放新添加的内容的主键,名称,字段名称 最后一个pop_id对应的是应为原来的筛选表中 #的name字段为 name="id_publishs" 的类型的 data = {"pk": new_obj.pk, 'val': new_obj.__str__(),'pop_id':'id_%s'%request.GET.get('pop_id')} import json data = json.dumps(data) #将内容返回到中间表中去 return render(request,'stark/pop_resp.html',{"data":data}) return redirect(list_url) else: return render(request, 'stark/add.html', {'my_form': myform})
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> <h3>这是POP response</h3> <script> {# 这是用pop打开添加页面完成添加功能后返回的页面#} {# 在此页面中调用 opener.foo 即是在调用他的父页面pop功能按键所在的页面, #} {# 并将数据传送给这个函数,为了避免将数据转意 用 |safe方法讲数据传过去 #} opener.foo('{{data|safe }}'); {# 将此页面关闭#} window.close(); </script> </body> </html>
浙公网安备 33010602011771号