popUp是啥?具体是啥我说不清,我理解为弹窗。你看看admin里面的 + 号。点击 + ,弹出的页面就是用popUp来实现的。
在stack项目中,有用到。
知识储备:
- 自执行函数:
流程:(刚开始看绕的一批,后来再看,还是很绕...)
首先肯定是要在添加页面或者编辑页面,你才可能会用到popUp。
先进入到add_view.html,load会执行change_form,change_form用到了inclusion_tag。
然后执行结果返回给form.html页面。其实也就是add页面了。
点击popUp请求,执行function,根据反向查找,展示popUp页面。
操作完成后,数据提交到add_views函数的post请求下面,会render一个 stark/popup_reponse.html
该页面下,触发自执行函数,并将值返回原函数页面。执行该函数popupcallback下操作
最后进行,正常的add操作。
该操作同样适用于编辑操作。在编辑页面编写同样代码即可。
1 def add_view(self,request,*args,**kwargs): 2 model_form_class = self.get_model_form_class() 3 _popbackid = request.GET.get(‘_popbackid‘) 4 if request.method == "GET": 5 form = model_form_class() 6 return render(request,‘stark/add_view.html‘,{‘form‘:form,‘config‘:self}) 7 else: 8 form = model_form_class(request.POST) 9 if form.is_valid(): 10 # 数据库中创建数据 11 new_obj = form.save() 12 print(‘new_obj‘,str(new_obj)) 13 if _popbackid: 14 # 是popup请求 15 # render一个页面,写自执行函数 16 # popUp(‘/stark/app01/userinfo/add/?_popbackid=id_consultant&model_name=customer&related_name=consultant‘) 17 18 from django.db.models.fields.reverse_related import ManyToOneRel, ManyToManyRel 19 result = {‘status‘:False,‘id‘:None,‘text‘:None,‘popbackid‘:_popbackid} 20 model_name = request.GET.get(‘model_name‘) # 获得当前所在的类名 customer 21 related_name = request.GET.get(‘related_name‘) # 获得related_name consultant related_name = request.GET.get(‘related_name‘) #获得related_name 22 # print(model_name,related_name,new_obj._meta.model_name) customer consultant userinfo 23 for related_obj in new_obj._meta.related_objects: 24 _model_name = related_obj.model._meta.model_name # 当前增加的表的名称 25 _related_name = related_obj.related_name # 当前表关联的related_name 26 27 if type(related_obj) == ManyToOneRel: # 判断如果是FK的话 28 _field_name = related_obj.field_name # code (to_field) 关联的字段 29 else: 30 _field_name = ‘pk‘ 31 _limit_choices_to = related_obj.limit_choices_to 32 print(‘471_limit_choices_to‘,_limit_choices_to) 33 if model_name == _model_name and related_name == str(_related_name): 34 is_exists = self.model_class.objects.filter(**_limit_choices_to,pk=new_obj.id).exists() 35 if is_exists: 36 # 如果是新创建用户是销售部的人, 页面才会显示该新增选项 37 result[‘status‘] = True 38 result[‘text‘] = str(new_obj) 39 result[‘id‘] = getattr(new_obj,_field_name) 40 print(result) 41 return render(request, ‘stark/popup_response.html‘,{‘json_result‘: json.dumps(result, ensure_ascii=False)}) 42 # result = {‘id‘:new_obj.pk, ‘text‘:str(new_obj),‘popbackid‘:_popbackid } 43 return render(request,‘stark/popup_response.html‘,{‘json_result‘:json.dumps(result,ensure_ascii=False)}) 44 else: 45 return redirect(self.get_list_url()) 46 return render(request, ‘stark/add_view.html‘, {‘form‘: form,‘config‘:self})
{% extends ‘stark/layout.html‘ %} {% load change_form %} {% block body %} <h1>添加页面</h1> {% form config form %} {% endblock %} 我们去看一看{% load change_form %}里面是什么?
from django.template import Library from django.urls import reverse from stark.service.v1 import site register = Library() @register.inclusion_tag(‘stark/form.html‘) def form(config,model_form_obj): new_form = [] for bfield in model_form_obj: temp = {‘is_popup‘: False, ‘item‘: bfield} # field是ModelForm读取对应的models.类,然后根据每一个数据库字段,生成Form的字段 from django.forms.boundfield import BoundField from django.db.models.query import QuerySet from django.forms.models import ModelChoiceField if isinstance(bfield.field, ModelChoiceField): related_class_name = bfield.field.queryset.model if related_class_name in site._registry: # 如果已经被注册 app_model_name = related_class_name._meta.app_label, related_class_name._meta.model_name # FK,M2M,O2O: 当前字段所在的类名,以及related_name model_name = config.model_class._meta.model_name related_name = config.model_class._meta.get_field(bfield.name).rel.related_name # print(‘6666666666‘,model_name,related_name) base_url = reverse("stark:%s_%s_add" % app_model_name) # 这里生成的url在?后会带着它的当前类名和related_name popurl = "%s?_popbackid=%s&model_name=%s&related_name=%s"%(base_url, bfield.auto_id,model_name,related_name) temp[‘is_popup‘] = True temp[‘popup_url‘] = popurl new_form.append(temp) return {‘form‘:new_form}
收工....