创建多对多以及增加示例
一,小碎知识
JSON 与 JS 对象的关系
很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
|
1
|
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的 |
|
1
|
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串 |
JSON 和 JS 对象互转
要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
|
1
|
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}' |
要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
json在Python里面的用法:
json.dumps : dict转成str
json.loads:str转成dict
二,多对多示例
1. 建2张表备用
class Host(models.Model):
nid=models.AutoField(primary_key=True)
hostname=models.CharField(max_length=32,db_index=True)
ip=models.GenericIPAddressField(protocol="ipv4",db_index=True)
port=models.IntegerField()
b=models.ForeignKey("Business",to_field='id')
class Application(models.Model):
name=models.CharField(max_length=32)
r=models.ManyToManyField("Host")
自动生成了一张app01_application_r的第3张表,来关联application与 host表。自动关联主键

2. 因为第3张表没有类,(不是根据类生成的),所以我们无法通过类直接对它进行操作。
在数据库中增加一些数据备用

3. 事实证明row.r.all() 确实是QuerySet类型。

4.在views.py中获取数据,然后把数据传送到前端。
views.py
def host(request):
v1=models.Host.objects.all()
v2= models.Host.objects.all().values('hostname','ip','port','b_id','b__caption')
return render(request,'host.html',{'v1':v1,'v2':v2})
def app(request):
app_list=models.Application.objects.all()
return render(request,'app.html',{"app_list":app_list})
app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>应用列表</h1>
<table border="1px">
<thead>
<tr>
<th>应用名称</th>
<th>应用主机列表</th>
</tr>
</thead>
<tbody>
{% for app in app_list %}
<tr>
<td>{{app.name}}</td>
<td>{{app.r.all}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
效果:从这里也可以看出来,app.r获取到的都是host对象。

5. 通过hostname获取到主机名字的列表。
<tbody>
{% for app in app_list %}
<tr>
<td>{{app.name}}</td>
<td>
{% for host in app.r.all %}
<span>{{host.hostname}}</span>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
效果:

6. 实现了成功添加,有个问题,如果应用主机列表含字母的话,则会报错。改成数字的话,则可以成功添加。后续待解决。

粘贴部分程序:
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^business/', views.business),
url(r'^host/', views.host),
url(r'^app/', views.app),
]
models.py
class Host(models.Model):
nid=models.AutoField(primary_key=True)
hostname=models.CharField(max_length=32,db_index=True)
ip=models.GenericIPAddressField(protocol="ipv4",db_index=True)
port=models.IntegerField()
b=models.ForeignKey("Business",to_field='id')
class Application(models.Model):
name=models.CharField(max_length=32)
r=models.ManyToManyField("Host")
views.py
def host(request):
v1=models.Host.objects.all()
v2= models.Host.objects.all().values('hostname','ip','port','b_id','b__caption')
return render(request,'host.html',{'v1':v1,'v2':v2})
def app(request):
if request.method=="GET":
app_list=models.Application.objects.all()
host_list = models.Host.objects.all()
return render(request,'app.html',{"app_list":app_list,'host_list':host_list})
elif request.method=="POST":
app_name=request.POST.get('app_name')
host_list = request.POST.getlist('host_list')
obj=models.Application.objects.create(name=app_name)
obj.r.add(*host_list)
return redirect('/app/')
app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.hide{
display:none;
}
.shade{
position:fixed;
top:0;
bottom:0;
right:0;
left:0;
background:black;
opacity:0.6;
z-index:100;
}
.add_modal,.edit_modal{
position:fixed;
height:300px;
width:400px;
top:10px;
left:50%;
z-index:101;
border:1px solid red;
background:white;
margin-left:-200px;
}
.host-tag{
display:inline-block;
padding:3px;
border:1px solid red;
background-color:pink;
}
</style>
</head>
<body>
<h1>应用列表</h1>
<div>
<input id="add_app" type="button" value="添加"/>
</div>
<table border="1px">
<thead>
<tr>
<th>应用名称</th>
<th>应用主机列表</th>
</tr>
</thead>
<tbody>
{% for app in app_list %}
<tr>
<td>{{app.name}}</td>
<td>
{% for host in app.r.all %}
<span class="host-tag">{{host.hostname}}</span>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="shade hide"></div>
<div class="add_modal hide">
<form id="add_form" method="POST" action="/app/">
<div>
<input id="app_name" type="text" placeholder="应用名称" name="app_name"/>
</div>
<div>
<select id="host_list" name="host_list" multiple>
{% for row in host_list %}
<option>{{row.hostname}}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="提交"/>
</form>
</div>
<script src="/static/jquery-1.12.4.js"></script>
<script>
$(function(){
$('#add_app').click(function(){
$('.shade,.add_modal').removeClass('hide');
})
$('#cancel').click(function(){
$('.shade,.add_modal').addClass('hide');
})
})
</script>
</body>
</html>
7. 用Ajax验证后再提交
dataType:'JSON':在内部做了一个把字符串转换成json对象的处理,返回的直接就是对象。 data:{'k':'v'}
traditional:True:在内部做了一个把列表转换成json对象的处理,返回的直接就是对象。 data:{'list':[1,2,3,4]}
data:$('#add_form').serialize():打包获取到add_form中的数据。 data:{'user':123,'host_list':[1,2]},
views.py
def app(request):
if request.method=="GET":
app_list=models.Application.objects.all()
host_list = models.Host.objects.all()
return render(request,'app.html',{"app_list":app_list,'host_list':host_list})
elif request.method=="POST":
app_name=request.POST.get('app_name')
host_list = request.POST.getlist('host_list')
obj=models.Application.objects.create(name=app_name)
obj.r.add(*host_list)
return redirect('/app/')
def ajax_add_app(request):
ret={'status':True,'error':None,'data':None}
app_name=request.POST.get('app_name')
host_list=request.POST.getlist('host_list')
obj = models.Application.objects.create(name=app_name)
obj.r.add(*host_list)
return HttpResponse(json.dumps(ret))
app.html---------需要完善
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.hide{
display:none;
}
.shade{
position:fixed;
top:0;
bottom:0;
right:0;
left:0;
background:black;
opacity:0.6;
z-index:100;
}
.add_modal,.edit_modal{
position:fixed;
height:300px;
width:400px;
top:10px;
left:50%;
z-index:101;
border:1px solid red;
background:white;
margin-left:-200px;
}
.host-tag{
display:inline-block;
padding:3px;
border:1px solid red;
background-color:pink;
}
</style>
</head>
<body>
<h1>应用列表</h1>
<div>
<input id="add_app" type="button" value="添加"/>
</div>
<table border="1px">
<thead>
<tr>
<th>应用名称</th>
<th>应用主机列表</th>
</tr>
</thead>
<tbody>
{% for app in app_list %}
<tr>
<td>{{app.name}}</td>
<td>
{% for host in app.r.all %}
<span class="host-tag">{{host.hostname}}</span>
{% endfor %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="shade hide"></div>
<div class="add_modal hide">
<form id="add_form" method="POST" action="/app/">
<div>
<input id="app_name" type="text" placeholder="应用名称" name="app_name"/>
</div>
<div>
<select id="host_list" name="host_list" multiple>
{% for row in host_list %}
<option>{{row.hostname}}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="提交"/>
<input id="add_submit_ajax" type="button" value="Ajax提交"/>
</form>
</div>
<script src="/static/jquery-1.12.4.js"></script>
<script>
$(function(){
$('#add_app').click(function(){
$('.shade,.add_modal').removeClass('hide');
});
$('#cancel').click(function(){
$('.shade,.add_modal').addClass('hide');
});
$('#add_submit_ajax').click(function(){
$.ajax({
url:'/ajax_add_app',
//data:{'user':123,'host_list':[1,2]},
data:$('#add_form').serialize(),
type:'POST',
dataType:'JSON',
traditional:true,
success:function(obj){
console.log(obj)
},
error:function(){
},
})
});
})
</script>
</body>
</html>
效果:

8.增加删除的功能。效果:编辑哪个,出来哪个,而且已经选中的列表默认也是选中的。

至此程序如下:
urls.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^business/', views.business),
url(r'^host/', views.host),
url(r'^app/', views.app),
url(r'^ajax_add_app',views.ajax_add_app)
]
models.py
from django.db import models
# Create your models here.
class Business(models.Model):
caption=models.CharField(max_length=32)
code = models.CharField(max_length=32, null=True)
class Host(models.Model):
nid=models.AutoField(primary_key=True)
hostname=models.CharField(max_length=32,db_index=True)
ip=models.GenericIPAddressField(protocol="ipv4",db_index=True)
port=models.IntegerField()
b=models.ForeignKey("Business",to_field='id')
class Application(models.Model):
name=models.CharField(max_length=32)
r=models.ManyToManyField("Host")
views.py
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
import json
# Create your views here.
def business(request):
v1=models.Business.objects.all()
return render(request,'business.html',{'v1':v1})
def host(request):
v1=models.Host.objects.all()
v2= models.Host.objects.all().values('hostname','ip','port','b_id','b__caption')
return render(request,'host.html',{'v1':v1,'v2':v2})
def app(request):
if request.method=="GET":
app_list=models.Application.objects.all()
host_list = models.Host.objects.all()
return render(request,'app.html',{"app_list":app_list,'host_list':host_list})
elif request.method=="POST":
app_name=request.POST.get('app_name')
host_list = request.POST.getlist('host_list')
obj=models.Application.objects.create(name=app_name)
obj.r.add(*host_list)
return redirect('/app/')
def ajax_add_app(request):
ret={'status':True,'error':None,'data':None}
app_name=request.POST.get('app_name')
host_list=request.POST.getlist('host_list')
obj = models.Application.objects.create(name=app_name)
obj.r.add(*host_list)
return HttpResponse(json.dumps(ret))
app.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.hide{
display:none;
}
.shade{
position:fixed;
top:0;
bottom:0;
right:0;
left:0;
background:black;
opacity:0.6;
z-index:100;
}
.add_modal,.edit_modal{
position:fixed;
height:300px;
width:400px;
top:10px;
left:50%;
z-index:101;
border:1px solid red;
background:white;
margin-left:-200px;
}
.host-tag{
display:inline-block;
padding:3px;
border:1px solid red;
background-color:pink;
}
</style>
</head>
<body>
<h1>应用列表</h1>
<div>
<input id="add_app" type="button" value="添加"/>
</div>
<table border="1px">
<thead>
<tr>
<th>应用名称</th>
<th>应用主机列表</th>
</tr>
</thead>
<tbody>
{% for app in app_list %}
<tr aid="{{app.id}}">
<td>{{app.name}}</td>
<td>
{% for host in app.r.all %}
<span class="host-tag" hid="{{host.nid}}">{{host.hostname}}</span>
{% endfor %}
</td>
<td>
<a class="edit">编辑</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="shade hide"></div>
<div class="add_modal hide">
<form id="add_form" method="POST" action="/app/">
<div>
<input id="app_name" type="text" placeholder="应用名称" name="app_name"/>
</div>
<div>
<select id="host_list" name="host_list" multiple>
{% for row in host_list %}
<option>{{row.hostname}}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="提交"/>
<input id="add_submit_ajax" type="button" value="Ajax提交"/>
</form>
</div>
<div class="edit_modal hide">
<form id="edit_form" method="POST" action="/host/">
<input type="text" name="nid" style="display:none"/>
<input type="text" placeholder="应用名称" name="app"/>
<select name="host_list" multiple>
{% for row in host_list %}
<option>{{row.hostname}}</option>
{% endfor %}
</select>
<a id="ajax_submit_edit" style="display:inline-block;padding:5px;background:blue;color:white">确认编辑</a>
</form>
</div>
<script src="/static/jquery-1.12.4.js"></script>
<script>
$(function(){
$('#add_app').click(function(){
$('.shade,.add_modal').removeClass('hide');
});
$('#cancel').click(function(){
$('.shade,.add_modal').addClass('hide');
});
$('#add_submit_ajax').click(function(){
$.ajax({
url:'/ajax_add_app',
//data:{'user':123,'host_list':[1,2]},
data:$('#add_form').serialize(),
type:'POST',
dataType:'JSON',
traditional:true,
success:function(obj){
console.log(obj)
},
error:function(){
},
})
});
$('.edit').click(function(){
$('.shade,.edit_modal').removeClass('hide');
var hid_list=[];
$(this).parent().prev().children().each(function(){
var hid=$(this).attr('hid');
hid_list.push(hid);
});
$('#edit_form').find('select').val(hid_list);
/*如果发送到后台
obj=models.Application.objects.get(id=aid)
obj.name='新name'
obj.save()
obj.r.set([1,2,3,4])
*/
})
})
</script>
</body>
</html>
host.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.shade={
position:fixed;
top:0;
bottom:0;
left:0;
right:0;
background:black;
opacity:0.6;
}
</style>
</head>
<body>
<h1>主机列表1</h1>
<div>
<input id="add_host" type="button" value="添加"/>
</div>
<table border="1">
<thead>
<tr>
<th>No.</th>
<th>hostname</th>
<th>IP</th>
<th>port</th>
<th>caption</th>
</tr>
</thead>
<tbody>
{% for row in v1 %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{row.hostname}}</td>
<td>{{row.ip}}</td>
<td>{{row.port}}</td>
<td>{{row.b.caption}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="shade"></div>
<script src="/static/jquery-1.12.4.js"></script>
<script>
$(function(){
$('#add_host').click(function(){
$('.shade,.add-modal').removeClass('hide');
})
})
</script>
</body>
</html>
浙公网安备 33010602011771号