Django - Xadmin (五) POP
功能及逻辑描述
pop 功能:在添加数据时,对于需要选择的多对多字段,在其 input 框边加上一个按钮,点击该按钮可以实现跳转到添加该字段数据的页面;添加该字段数据后,添加字段数据页面消失,返回到原来添加页面;此时新添加的内容已经出现在选项中并默认选中。
页面跳转与消失的逻辑
跳转逻辑:
window.open(url, "", "400,height=200,top=100,left=100")
window.open 函数指定跳转的 url ,出现的位置和新窗口的大小。
页面自动消失的逻辑:
在前面跳转到的页面中的 script 中加上 window.close();
可以实现页面自动关闭,而如果想在页面关闭之前要实现一些业务逻辑可以将代码写在该代码之前。如果要实现的业务逻辑需要用到跳转到该页面之前的母页面,可以使用 window.opener.母页面中的函数
的方式。
后台处理
主要是在 add_view 视图函数中进行处理。
添加数据主要是通过 ModelForm 组件实现的,先对构造该类时进行更改。
# 实现pop功能
for bfield in form:
# 字段对象
# print(bfield.field)
# print(type(bfield.field)) # 字段类型
# print("name", bfield.name) # 字段名
if isinstance(bfield.field, ModelChoiceField):
# 如果是一对多或多对多字段,需要pop功能
bfield.is_pop = True
# print(bfield.name, "=====>", bfield.field.queryset.model)
# bfield.field.queryset.model是所关联的模型表
related_model_name = bfield.field.queryset.model._meta.model_name
related_app_label = bfield.field.queryset.model._meta.app_label
_url = reverse("%s_%s_add"%(related_app_label, related_model_name))
bfield.url = _url+"?pop_res_id=id_%s"%bfield.name
对在 ModelForm 类中的每个字段进行判断,如果是一对多或者多对多字段则认定需要 pop 功能。获取字段关联的模型表,并通过 reverse 函数得到该字段 pop 时需要的 url ,添加到该字段的 url 属性当中。
# 从前端传回数据
if request.method == "POST":
form = ModelFormDemo(request.POST)
# 通过校验,保存并返回到查看页面
if form.is_valid():
obj = form.save()
pop_res_id = request.GET.get("pop_res_id")
# 按pop方式打开,返回到之前添加页面
if pop_res_id:
res = {"pk":obj.pk, "text": str(obj), "pop_res_id":pop_res_id}
return render(request, "pop.html", {"res": res})
# 如果不是经过pop打开,按正常方式返回
else:
return redirect(self.get_list_url())
对于从前端传回来的数据进行添加到数据库中的操作,现在多了一步,就是判断是否按 pop 方式打开,是则返回之前添加页面,并传回新添加数据的信息。
前端处理
form.html
{% for field in form %}
<div style="position: relative">
<label for="">{{ field.label }}</label>
{{ field }}
<span class="error pull-right">{{ field.errors.0 }}</span>
{% if field.is_pop %}
<a onclick="pop('{{ field.url }}')" style="position: absolute;right: -30px;top: 20px;"><span style="font-size: 28px;">+</span></a>
{% endif %}
</div>
{% endfor %}
<script>
function pop(url) {
// alert(url);
window.open(url, "", "400,height=200,top=100,left=100")
}
</script>
在循环 ModelForm 表单的时候判断是否为需要 pop 功能的字段,如果是,增加 pop 链接。然后为 pop 功能绑定跳转页面函数。
pop.html
<script>
// 调用该窗口的窗口执行该函数
window.opener.pop_response('{{ res.pk }}', '{{ res.text }}', '{{ res.pop_res_id }}');
window.close();
</script>
作为中转的临时页面,pop.html 就是负责调用母页面的函数并自动消失。
add_view.html
<script>
function pop_response(pk, text, id) {
console.log(pk);
console.log(text);
console.log(id);
// 选择相应的select标签
// option文本值和value值
var $option = $('<option>');// 创建标签
$option.html(text); // 加文本
$option.val(pk); // 加value
$option.attr("selected", "selected"); // 加属性
$("#"+id).append($option); // 将option标签加上去
}
</script>
add_view.html 中的逻辑就是将获取到的,新添加数据的信息增加到 option 标签中并默认选中。
完整代码地址:pop 功能