一、先看下什么django的admin的pop到底是个什么东西

其实就是这么一个东西,

a、在添加页面,在一对多和多对多的项后加了一个+号

b、点击这个加号,会弹出对应的添加 页面,在新的添加

c、添加完成后,新打开的页面自动关闭,然后把新添加数据的添加到对应的框中

二、下面我们来实现pop功能

a、知识点1,实现点击按钮,弹出一个新的窗口这个功能

首先我们写一个如下的html文件,点击这个文件,会重新打开一个窗口

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="button"> <script src="/static/jq/jquery-3.3.1.js"></script>
<script>
$("input").bind("click",function () {
{# window.open实现弹出一个新的窗口,然后打开我们对应的的url#}
window.open("/test_add/",'','width=400px,height=400px,top=100px,left=200px')
}) function bar(args) {
console.log(args)
}
</script>
</body>
</html>

  

效果如下

点击后的效果

添加窗口的html代码如下

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
{% csrf_token %}
书籍名称:<input type="text" name="name">
<input type="submit" value="submit"> </form>
</body>
</html>

  

然后我们看下这个form表单对应的视图函数

from app1 import models
def test_add(request):
if request.method == "POST":
name = request.POST.get("name")
models.test.objects.create(
name = name
) return render(request,"pop.html",{'name':name}) else:
return render(request,"test_add.html")

  

这里的代码我们要分析一下了、

这里为什么返回一个页面呢? 其实主要实现的效果就是添加成功,返回pop这个html文件,然后在pop的html文件中,我们会直接关闭窗口,另外我们这里进行了传参,主要是为了把当前添加的数据渲染到之前我们点击添加按钮的页面上

下面我们看下pop的html的代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="/static/jq/jquery-3.3.1.js"></script> <script> {# 打开当前这个窗口对象#}
window.opener.bar('{{ name }}') {# 实现关闭页面的效果#}
window.close()
</script>
</body>
</html>

  

这里的代码还是需要解释一下,

这个是执行打开这个窗口的那个对象中的bar函数

这个是关闭当前的页面

我们最后看下bar函数,这样我们就可以实现在子页面和父页面之间进行数据传递的效果了

三、最后我们在我们的stark组件中实现pop功能

1、首先我们需要在每个input标签后面加一个“+”号

           {% for field in form_obj %}
<div style="position: relative">
<label>{{ field.label }}</label>:
{{ field }}
<span class="pull-right">{{ field.errors.0 }}</span>
{# {% if field.pop %}#}
<a href="#" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>
{# {% endif %}#}
</div>
{% endfor %}

  

页面的效果如下

2、下面我们要判断,不能在所有的input标签后面弄一个加号,必须是一对多,或者多对多的才加,我们首先看下前端渲染的form_obj的类型是什么

    def add_url(self,request):
model_name = self.model._meta.model_name
app_name = self.model._meta.app_label
# print(model_name,app_name,"============================")
print(self.model)
form_obj = self.get_model_form_class()
form_obj = form_obj()
print("form_obj",form_obj,type(form_obj))
from django.forms.boundfield import BoundField
from django.forms.models import ModelMultipleChoiceField
from django.forms.models import ModelChoiceField
if request.method == "GET":
for i in form_obj:
# if isinstance(i.field,(ModelMultipleChoiceField,ModelChoiceField)):
# i.pop = True
print(i,type(i),sep="-------------")
return render(request,"add_view.html",locals())
else:
form_obj = form_obj(request.POST)
if form_obj.is_valid():
form_obj.save()
path = "/stark/{app}/{model}".format(app=app_name,model=model_name)
return redirect(path) return render(request,"add_view.html",locals())

  

输出如下

我们看到所有的字段的类型都是一个类型,我们导入这个类看下这个类有什么方法

from django.forms.boundfield import BoundField

  

我们试着打印这个filed的属性的值和type

        from django.forms.boundfield import BoundField
from django.forms.models import ModelMultipleChoiceField
from django.forms.models import ModelChoiceField
if request.method == "GET":
for i in form_obj:
# if isinstance(i.field,(ModelMultipleChoiceField,ModelChoiceField)):
# i.pop = True
print(type(i.field),sep="-------------")
return render(request,"add_view.html",locals())

  

结果如下

这里我们可以判断,如果字段是ModelMultipleChoiceField和ModelChoiceField的实例对象,则才加 加号

我们这里这样做,如果是ModelMultipleChoiceField和ModelChoiceField的实例对象,我们为这个实例对象赋值一个属性pop = true,然后我们在前端渲染的时候,判断有有个属性,则加 一个加号

后端的代码如下

        model_name = self.model._meta.model_name
app_name = self.model._meta.app_label
# print(model_name,app_name,"============================")
print(self.model)
form_obj = self.get_model_form_class()
form_obj = form_obj()
print("form_obj",form_obj,type(form_obj))
from django.forms.boundfield import BoundField
from django.forms.models import ModelMultipleChoiceField
from django.forms.models import ModelChoiceField
if request.method == "GET":
for i in form_obj:
if isinstance(i.field,(ModelMultipleChoiceField,ModelChoiceField)):
i.pop = True
print(type(i.field),sep="-------------")

  

前端的代码如下

            <div class="col-md-4 col-lg-offset-4" >
{% for field in form_obj %}
<div style="position: relative">
<label>{{ field.label }}</label>:
{{ field }}
<span class="pull-right">{{ field.errors.0 }}</span>
{% if field.pop %}
<a href="#" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>
{% endif %}
</div>
{% endfor %}
</div>

  

页面效果如下

2、下面我们实现点击加号弹出对应的框

首先我们为a标签绑定一个单机的事件,点击这个按钮执行pop函数

                  {% if field.pop %}
{# <a onclick="pop('{{ field.url }}')" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>#}
<a onclick="pop()" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>
{% endif %}

  

我们下面看下pop函数

    function pop() {
alert(123)
}

  

点击按钮,看到我们的函数已经绑定上了

下面我们就是要实现点击按钮打开一个窗口的效果,首先我们需要拿到每个字段的的url

        if request.method == "GET":
for i in form_obj:
if isinstance(i.field,(ModelMultipleChoiceField,ModelChoiceField)):
i.pop = True
print(dir(i.field.queryset.model),dir(i.field.queryset.model._meta),sep="-------------")
args1 = i.field.queryset.model._meta.model_name
args2 = i.field.queryset.model._meta.app_label
_url = "/stark/{args2}/{args1}/add".format(args1=args1,args2=args2)
i.url = _url return render(request,"add_view.html",locals())

  

先判断是否为一对多或者多对多,然后调用方法获取跨表的app的名称和表的名称

然后拼接url,然后为这个字段赋值一个url的属性

然后最后在html文件中接收一个url的参数

            {% for field in form_obj %}
<div style="position: relative">
<label>{{ field.label }}</label>:
{{ field }}
<span class="pull-right">{{ field.errors.0 }}</span>
{% if field.pop %}
<a onclick="pop('{{ field.url }}')" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>
{# <a onclick="pop()" style="position: absolute;right: -30px;top: 30px"><span style="font-size: 20px">[+]</span></a>#}
{% endif %}
</div>

  

最后我们看下pop函数

    function pop(url) {
window.open(url,"","")
}

  

最后我们看下页面的效果

至此,这一部分我们已经讲解完了

3、最后我们在实现这个功能,在弹出的新增的窗口添加新的数据,然后新添加的数据被添加到select标签中,且被选中的状态

首先我们要为每个点击加号点开的窗口添加一个url的参数,用来判断我这次添加的是哪张表的内容

        if request.method == "GET":
form_obj = form_obj()
for i in form_obj:
if isinstance(i.field,(ModelMultipleChoiceField,ModelChoiceField)):
i.pop = True
args1 = i.field.queryset.model._meta.model_name
args2 = i.field.queryset.model._meta.app_label
_url = "/stark/{args2}/{args1}/add".format(args1=args1,args2=args2)
i.url = _url + "?pop_res_id=" + "id_" + args1 return render(request,"add_view.html",locals())

  

然后我们测试点击加号弹出的窗口的url

get方式处理完成,下面我们看下post的请求的处理

首先判断一下GET的参数中是否有pop_res_id这个变量,如果有的话,则走我们的pop处理的流程,如果没有的话,则走正常的添加的流程

            model_form_obj = form_obj(request.POST)
if model_form_obj.is_valid():
res = model_form_obj.save()
pop_res_id = request.GET.get("pop_res_id",None) if pop_res_id:
pop_dict = {"pk":res.id,"text_name":str(res),"field":pop_res_id}
return render(request,"test_pop.html",{"pop_dict":pop_dict})
else: path = "/stark/{app}/{model}".format(app=app_name,model=model_name)
return redirect(path) return render(request,"add_view.html",locals())

  

如果走pop的添加流程,则需要借助一个save函数的返回值,因为我们后面要添加标签,所以这3个参数是必不可少的

然后我们在看下pop的html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="/static/jq/jquery-3.3.1.js"></script> <script> {# 打开当前这个窗口对象#}
window.opener.bar('{{ pop_dict.field }}','{{ pop_dict.pk }}',"{{ pop_dict.text_name }}"); {# 实现关闭页面的效果#}
window.close()
</script>
</body>
</html>

  

在看添加页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css"> <style>
input,select {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
}
</style>
</head>
<body>
<h4>编辑页面</h4>
{% include "form.html" %} <script src="/static/jq/jquery-3.3.1.js"></script>
<script>
function bar(field,pk,text_name) {
var $option = $('<option>');
$option.html(text_name);
$option.val(pk);
$option.attr("selected","selected");
$("#" + field).append($option)
}
</script>
</body>
</html>

  

根据参数,创建option标签,且让他处于选中的状态

最后我们看下页面的效果

页面会实现自动选中的效果

至此pop的功能我们已经全部实现,还是比较复杂的

stark组件之pop操作【模仿Django的admin】的更多相关文章

  1. stark组件之批量操作【模仿Django的admin】

    一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...

  2. stark组件之注册【模仿Django的admin】

    一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...

  3. stark组件之搜索【模仿Django的admin】

    一.先看下django的admin是如何做搜索功能的 配置一个search_fields的列表就可以实现搜索的功能 class testbook(admin.ModelAdmin): # 第一步,定义 ...

  4. stark组件之启动【模仿Django的admin】

    首先需要在settings注册app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib ...

  5. stark组件之分页【模仿Django的admin】

    我们的stark组件用的我们的分页组件,没有重新写 下面直接看下分页的代码 class page_helper(): def __init__(self, count, current_page, p ...

  6. stark组件之路由分发【模仿Django的admin】

    一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...

  7. stark组件之过滤操作【模仿Django的admin】

    一.先看下django的admin是如何实现过滤操作 首先在配置类中顶一个list_filter的列表,把要过滤的字段作为元素写i进去就可以了 class testbook(admin.ModelAd ...

  8. stark组件之pop页面,按钮,url,页面

      1.Window open() 方法 2.admin的pop添加按钮 3.stark之pop功能 3.知识点总结 4.coding代码 1.Window open() 方法 效果图   2.adm ...

  9. 12 stark组件之pop,按钮,url,页面

    1.Window open() 方法 http://www.runoob.com/jsref/met-win-open.html 效果图   2.admin的pop添加按钮 3.stark之pop功能 ...

随机推荐

  1. putty登录显示IP

    登陆服务器 cd vi .bashrc 在尾部加入如下代码 if [ "$SSH_CONNECTION" != '' -a "$TERM" != 'linux' ...

  2. elasticsearch-ik

    因lucene默认采用英文且英文通过空格就可以断句.而中文则是词组,如果不加载中文词库或插件则会变为一个一个字而非词组,因此需要加载中文词库. 不加分词库所看到的中文分词效果. post _analy ...

  3. JSONArray 遍历

    JSONArray 遍历   刚遇到一个接接口任务,发现其中返回数据中,是个字符串数组,数组中就是单个json形式的内容,其实应该也可以称这种数据叫做json数组吧,只不过是字符串形式.而我需要的是将 ...

  4. 【转】 DOTA2中的伪随机及其lua实现

    因为单纯的随机确实会影响到竞技性,所以dota2引入的是伪随机机制,在大量的技能中,比如说混沌的混乱之箭.剑圣的剑舞.冰女的冰霜领域之类的技能,都利用了伪随机机制. 而纯随机,或者标准正态分布并不会因 ...

  5. 转:用JS获取地址栏参数的方法(超级简单)

    转载链接: http://www.cnblogs.com/fishtreeyu/archive/2011/02/27/1966178.html 方法一:采用正则表达式获取地址栏参数:( 强烈推荐,既实 ...

  6. 何谓domReady

    我的博客已经写过好几篇如何实现domReady的文章,最近做培训,面向新手们,需要彻彻底底向他们说明这个东西,于是就有了这篇文章. 我们经常看人们用 document.getElementById(& ...

  7. Android 设备,如何root,执行adb shell,查看设备中的数据库信息等【转】

    原文地址: Android 设备,如何root,执行adb shell,查看设备中的数据库信息等

  8. week06 07 创建RPC SERVER 换个镜像安装下载

    RPC server 使用python类库 https://pypi.org/project/python-jsonrpc/ 和NPM 不一样 他没有global选项 他安装的就是全局的安装的类库叫p ...

  9. 如何配置eclipse的安卓SDK下载目录

    首先,打开eclipse,主界面如图 2 点击Windows下的preference 3 然后在出现的对话框中选择“android” 4 然后我们就能看到的主界面,在这里输入android sdk的目 ...

  10. 把Swift中的String转成NSString ,获取NSString的方法

    1.0 在Swift中的 String 并没有提供什么方法,直接把它自身转变成 Int .Float 等,而在OC中我们就可以这样  "123".integerValue 来获取它 ...