Xadmin弹出窗口
Xadmin弹出窗口
需求分析:
1.在添加页面的一对多和多对多字段后面加上+,点击+后,能显示出添加相应字段的窗口
2.提交后窗口关闭,添加的内容显示到当前页面
1.判断出当前字段是否为ForeignKey或ManyToManyField,
如果是则在后面添加+,不是则不添加。如果不进行判断,每个字段后面都会有+
{% for foo in form_obj %}
<div class="form-group" style="position: relative">
<label for="">{{ foo.label }}</label>
{{ foo }} <span> {{ foo.errors.}}</span>
<a><span style="font-size: 22px;color: #1b6d85;position: absolute;top: 27px;right:-23px">+</span></a>
</div>
{% endfor %}
1.在add函数中渲染页面时进行判断:
form_obj = DemoModelForm()
for i in form_obj: i为每个字段对象
print(type(i)) #<class 'django.forms.boundfield.BoundField'>
打印后所有的字段对象类型均为<class 'django.forms.boundfield.BoundField'>
导入 from django.forms.boundfield import BoundField查看其源码:
class BoundField(object):
def __init__(self, form, field, name):
self.form = form
self.field = field
self.name = name
self.html_name = form.add_prefix(name)
根据源码分析,字段类型有可能在field中,打印查看
from django.forms.boundfield import BoundField
for i in form_obj:
print(type(i.field))
<class 'django.forms.fields.DateField'>
<class 'django.forms.fields.DecimalField'>
<class 'django.forms.models.ModelChoiceField'>
<class 'django.forms.models.ModelMultipleChoiceField'>
2.在后端对符合条件的对象设置属性:
from django.forms.boundfield import BoundField
from django.forms.models import ModelChoiceField
for boundfield in form_obj:
print(type(boundfield.field))
#只要字段关系类型属于ModelChoiceField,那么就是ForeignKey或ManyToManyField
#为这个字段对象设置属性,在前端页面通过这个属性值及进行相应设置
if isinstance(boundfield.field,ModelChoiceField):
boundfield.is_pop = True return render(request, 'add_view.html', locals())
3.在前端通过其属性来加+
<form action="" method="post" novalidate >
{% csrf_token %}
{% for foo in form_obj %}
<div class="form-group" style="position: relative">
<label for="">{{ foo.label }}</label>
{{ foo }} <span> {{ foo.errors.}}</span>
{% if foo.is_pop %}
<a "><span style="font-size: 22px;color: #1b6d85;position: absolute;top: 27px;right:-23px">+</span></a>
{% endif %} </div>
{% endfor %}
<input type="submit" class="btn btn-default">
</form>
前端中form_obj值对应后端的form_obj,foo对应boundfield,因此foo.is_pop=boundfield.is_pop
2.点击+后,需要弹出对应的添加窗口。
1.比如,点击出版社,弹出的应该是出版设的添加窗口
点击作者,弹出的是作者的添加窗口。窗口的打开路径应该就是对应表的添加路径
< a onclick = "pop('{{ url }}')" > < span> + < / span > < / a >
2.需要根据当前这个字段,如果是publish,就找到Publish的添加数据路径,如果是authors,就找到Author表的数据添加路径
找到对应表的添加路径,就需要知道该字段连接的表的app和小写的表名。
在ModelForm中能通过字段关系得到该表的类
print(boundfield.field.queryset.model) #<class 'app01.models.Publish'
3.拿到app和表名后,通过反向解析找到publish或Author的添加路径,为了后续添加到当前操作页面,让窗口打开的网页加上参数
显示这种形式Xadmin/app01/publish/add/?pop_id=id_publish
以当前字段标签的id作为参数
boundfield.auto_id 字段对象.auto_id 自动匹配到该id
views.py 弹出窗口GET请求时的操作
def add_view(self, request):
form_obj = DemoModelForm()
###判断字段的类型###
# print("form_obj是:",form_obj)
from django.forms.boundfield import BoundField
from django.forms.models import ModelChoiceField
for boundfield in form_obj:
print(type(boundfield.field))
#只要字段关系类型属于ModelChoiceField,那么就是ForeignKey或ManyToManyField
#为这个字段对象设置属性,在前端页面通过这个属性值及进行相应设置
if isinstance(boundfield.field,ModelChoiceField):
boundfield.is_pop = True
#获得该字段连接的表和所在的app
print(boundfield.field.queryset.model) #<class 'app01.models.Publish'>
model_class=boundfield.field.queryset.model
app_name=model_class._meta.app_label
model_name=model_class._meta.model_name
#反响解析,得到该表添加数据的路径
url_name = "{}/{}_add".format(app_name, model_name)
url = reverse(url_name)
#获得该字段在页面上标签的id,自动匹配
print(boundfield.auto_id) #id_publish
boundfield.url=url+'?pop_id=%s'%boundfield.auto_id return render(request, 'add_view.html', locals())
form.HTML
<form action="" method="post" novalidate >
{% csrf_token %}
{% for foo in form_obj %}
<div class="form-group" style="position: relative">
<label for="">{{ foo.label }}</label>
{{ foo }} <span> {{ foo.errors.}}</span>
#字段关系判断
{% if foo.is_pop %}
<a onclick="pop('{{ foo.url }}')"><span style="font-size: 22px;color: #1b6d85;position: absolute;top: 27px;right:-23px">+</span></a>
{% endif %} </div>
{% endfor %}
<input type="submit" class="btn btn-default">
</form>
<script>
function pop(url) {
window.open(url,"","wdith=500,height=300,top=200,left=200")
}
</script>
3.add POST请求
1.弹出对应添加窗口后,添加完数据提交后,要将数据添加到对应的库中。然后将数据返回到"大窗口"的页面上
2.在使用ModelForm时,使用form_obj.save()就会自动保存,保存之后,需要做到是大窗口添加
的数据不返回,小窗口添加的数据返回,怎么判断是页面添加还是窗口添加的
3.在窗口返回路由时,为其配置了参数,可以通过判断这个参数是否存在,存在则是小窗口添加,就做返回数据的操作
页面添加的地址:Xadmin/app01/book/add/
小窗口添加的地址:/Xadmin/app01/author/add/?pop_id=id_authors
if request.method=='POST':
form_obj=DemoModelForm(request.POST)
if form_obj.is_valid():
obj=form_obj.save()
#判断是页面添加还是窗口添加
pop_id=request.GET.get("pop_id")
if pop_id:
text=str(obj) #文本内容为此对象str的返回值
#返回关闭窗口的页面
return render(request,"pop.html",locals())
else:
# return redirect(list_url) #不能用,相当于在当前路径后面拼接
return redirect(se
4.对关闭窗口页面的操作
在关闭窗口之前,需要将在窗口中添加的出版社名字或者作者名字传到显示页面上,POST请求将loacls()传给了
这个窗口关闭页面,在这个页面我们取到在显示页面需要的数据,如要新建对象的id显示的文本内容,添加到字段的id,
pop.html
<script>
window.opener.bar("{{ obj.pk }}","{{ text }}","{{ pop_id }}");
window.close()
</script>
5.在显示页面处理窗口关闭页面的数据
<select name="publish" required="" id="id_publish">
<option value=" " selected="">---------</option>
<option value="">昌平出版社</option>
<option value="">西二旗出版社</option>
<option value="">汇德出版社</option>
<option value="">天青烟雨出版社</option>
<option value="">江南出版社</option>
</select>
显示页面上出版社的代码如上,我们需要将添加的数据构成这种样式,<option value="2">昌平出版社</option>添加到select标签中
<script src="/static/jquery-3.3.1.js"></script>
<script>
function bar(pk,text,pop_id){
var $new_tag=$("<option></option>");
$new_tag.html(text);
$new_tag.attr("value",pk);
{# 设置默认选中 #}
$new_tag.attr("selected","selected");
添加标签
$("#"+pop_id).append($new_tag)
}
</script>
由于在创建标签时,使用的时jquery对象,因此要进入jquery-3.3.1.js,如果不引入,则新建数据在页面显示失败
Xadmin弹出窗口的更多相关文章
- jQuery弹出窗口浏览图片
效果预览:http://keleyi.com/keleyi/phtml/jqtexiao/3.htm HTML文件代码: <!DOCTYPE HTML> <html> < ...
- EasyUI弹出窗口实例
效果体验:http://hovertree.com/texiao/jeasyui/1.htm 源代码下载:HovertreeJEasyUI HTML文件代码: <!DOCTYPE html> ...
- 让IE8在win7下面能显示使用window.showmodaldialog弹出窗口的地址状态栏
问题来源:最近又要对老的系统进行改善,由于用到了window.showmodaldialog这个方法弹出窗口,比如从主界面弹出新增或者修改窗口,如下图所示,显示没有地址栏,进行代码修改还要找到相应的文 ...
- java selenium (十二) 操作弹出窗口
selenium 中如何处理弹出窗口 阅读目录 原理 在代码里, 通过 Set<String> allWindowsId = driver.getWindowHandles ...
- JSP弹出窗口和模式对话框
本文转载于其它blog,在此向本文原创者,致意! JSP 弹出窗口 一.window.open() 基础知识 1.window.open()支持环境: JavaScript1.0+ ...
- [转]js来弹出窗口的详细说明
1.警告对话框 <script> alert("警告文字") </script> 2.确认对话框 <script> confirm(" ...
- OAF_开发系列08_实现OAF通过Popup参数式弹出窗口(案例)
20150711 Created By BaoXinjian
- 【CefSharp】 禁用右键菜单 与 控制弹出窗口的方式(限版本39.0.0.1)
这周没什么时间,一开始就在忙一些CefSharp的事情,Win10的研究就放了下来,CefSharp的资料挺少的,但好在是开源的,可以我们便宜的折腾.因为两个的内容都不多,我就合成一篇文章啦. 这还里 ...
- jquery-通过js编写弹出窗口
本文转载 本文主要是通过js动态控制div的高度,css控制浮动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// ...
随机推荐
- nginx 代理flask应用的uwsgi配置
socket代理配置: 关于uwsgi的用法,请自行百度,这里只针对socket文件和端口的不同,进行单一的记录. 这种方式启动的flask应用,由于是通过socket与nginx通信的,所以必须制定 ...
- 【剑指offer】求树中满足和为给定数字的路径
题目: 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大的 ...
- 基础 - 获得CPU主频
// 获得cpu主频.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <windows.h> #include ...
- ubuntu crontab python 定时任务备记
crontab -e 写入: # at a.m every week with: # * * tar -zcf /var/backups/home.tgz /home/ # # For more in ...
- 20165312 2017-2018-2 《JAVA程序设计》第5周学习总结
20165312 2017-2018-2 <JAVA程序设计>第5周学习总结 一.本周学习内容总结 总的来说,本周学习较吃力,在理解第十章的代码时速度较慢. 内部类 内部类是定义在一个类中 ...
- Promise的实现原理
1.Promise 介绍 Promise类似一个事务管理器,将用户异步操作流程用流水的形式来表达,用来延迟deferred和异步asynchronous. 特点如下: (1)对象的状态不受外界影响 P ...
- Linux安装rz/sz,htop插件
Linux下rz/sz安装及使用方法 sz: 将选定的文件发送(send)到本地机器; rz:运行该命令会弹出 一个文件选择窗口, 从本地选择文件上传到服务器(receive). 下载安装包 lrzs ...
- 通过WebClient模拟post上传文件到服务器
写在前面 最近一直在研究sharepoint的文档库,在上传文件到文档库的过程中,需要模拟post请求,也查找了几种模拟方式,webclient算是比较简单的方式. 一个例子 这里写一个简单接受pos ...
- sqlserver数据库镜像运行模式
运行模式: 从大层面来说,SQL Server镜像只有两种模式:高安全模式和高性能模式.两种模式的主要区别在于在事务提交后的操作.可以从图1-1中查看运行模式. 在高性能模式下,主体服务器不需要等待镜 ...
- VUE图片懒加载-vue lazyload插件的简单使用
序:vue项目时候,我们要对图片进行懒加载处理,这个开发项目中就不需要自己去写了,因为比较方便使用vue lazyload进行处理,高效率开发 一. vue lazyload插件: 插件地址:http ...