Django-website 程序案例系列-7 创建多对多关系表
创建多对多关系表:
方式一:一共三张表其中有一张中间表需要手工建立(建议使用第一种方式自定制程度高)
class Host(models.Model):
hostname = models.CharField(max_length=32, db_index=True)
ip = models.GenericIPAddressField(db_index=True,protocol="ipv4")
port = models.IntegerField()
b = models.ForeignKey('Business', to_field='id') class Application(models.Model):
name = models.CharField(max_length=32) class HostToApp(models.Model): #多对多关系的中间表
hobj = models.ForeignKey(to='Host', to_field='id')
aobj = models.ForeignKey(to='Application', to_field='id')
方式二:一共两张表没有中间表,中间表又django自动生成(默认只能生成3列数据,如果需要更多数据就需要使用方式一来建立多对多关系)
class Host(models.Model):
hostname = models.CharField(max_length=32, db_index=True)
ip = models.GenericIPAddressField(db_index=True,protocol="ipv4")
port = models.IntegerField()
b = models.ForeignKey('Business', to_field='id') class Application(models.Model):
name = models.CharField(max_length=32)
r = models.ManyToManyField("Host") #建立多对多的关系,django自动生成中间表 #操作第三章表
obj = Application.objects.get(id=1)
obj.r.add(1) #增加第三张表的关系
obj.r.add(2,3)
obj.r.add(*[1,2,3,4]) obj.r.remove(1) #删除
obj.r.remove(2,3)
obj.r.remove(*[1,2,3])
obj.r.clear() #清空
obj.r.set([3,5,7]) #修改
obj.r.all() #获取所有相关host对象列表(QuerySet)
views.py
#传统模式使用GET和POST方式来接收表单数据
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') #拿到前端传来的增加app的名字
host_list = request.POST.getlist('host_list') #拿到前端传来的增加host关联的数据,使用getlist()获取列表
obj = models.Application.objects.create(name=app_name) #Application表中创建新的appname
obj.r.add(*host_list) #创建第三章表中的关系数据
return redirect('/app') #刷新页面
#使用aja来实现表单数据的接收
def ajax_add_app(request):
ret = {'status': True, 'error': None, 'data': None} #设置一个json格式的字符串
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)) #返回一个json格式的字符串
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.host-tag{ #显示主机关系标签的样式
display: inline-block;
padding: 3px;
border: 1px solid red;
background-color: #0169eb;
}
.hide{
display: none;
}
.shade{
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: black;
opacity: 0.6;
z-index: 100;
}
.add-modal,.edit-modal{
position: fixed;
height: 300px;
width: 400px;
top: 100px;
left: 50%;
z-index: 101;
border: 1px solid black;
background: white;
margin-left: -200px;
}
</style>
</head>
<body> <h1>应用列表</h1>
<div>
<input type="button" id="add_host" value="添加"/>
</div>
<table border="1">
<thead>
<tr>
<td>应用名称</td>
<td>应用主机列表</td>
</tr>
</thead>
<tbady>
{% for app in app_list %} #添加页面中显示Application表的相关信息
<tr aid="{{ app.id }}">
<td>{{ app.name }}</td>
<td>
{% for host in app.r.all %} #通过中间表拿到主机表信息
<span class="host-tag" hid="{{ host.id }}">{{ host.hostname }}</span>
{% endfor %}
</td>
<td>
<a class="edit">编辑</a>
</td>
</tr>
{% endfor %}
</tbady>
</table>
<div class="shade hide"></div>
<div class="add-modal hide">
<form action="/app" method="POST" id="add_form">
<div class="group">
<input type="text" id="host" placeholder="应用名称" name="app_name"/>
</div>
<div class="group">
<select id="host_list" name="host_list" multiple>
{% for op in host_list %}
<option value="{{ op.id }}">{{ op.hostname }}</option>
{% endfor %}
</select>
</div>
<input type="submit" value="提交"/>
<input type="button" id="cancel" value="取消"/>
<input type="button" id="add_submit_ajax" value="ajax提交"/> </form>
</div>
<div class="edit-modal hide"> #编辑Application表页面(修改)
<form action="/host" method="POST" id="edit_form" >
<input type="text" name="hid" style="display: none;"/>
<input type="text" placeholder="应用名称" name="app"/>
<select name="host_list" multiple>
{% for op in host_list %}
<option value="{{ op.id }}">{{ op.hostname }}</option>
{% endfor %}
</select>
<a id="ajax_submit_edit">确认编辑</a>
</form>
</div> </body> <script src="static/js/jquery.min.js"></script>
<script>
$(function() {
$('#add_host').click(function () {
$('.shade,.add-modal').removeClass('hide');
});
$('#cancel').click(function () {
$('.shade,.add-modal').addClass('hide');
}); $('#add_submit_ajax').click(function () { #增加Application表操作的JS
$.ajax({
url: '/ajax_add_app', #对应的url
//data: {'user': 123, 'host_list': [1,2,3,4]}, #使用传统方式传数据
data: $('#add_form').serialize(), #使用简单的方式,直接使用<form>表单的ID然后serialize()直接自动形成键值方式提交
type: "POST", #使用POST方式提交
dataType: 'JSON', #使用JSON格式
traditional: true, #开启列表接收,如‘host_List’: [1,2,3,4]这样后台就能拿到列表
success: function (obj) {
console.log(obj); #前端调试台打印响应的数据
},
error: function () { }
})
}); $('.edit').click(function () {
$('.edit-modal,.shade').removeClass('hide'); hid_list = []; #设置一个空列表
$(this).parent().prev().children().each(function () { #信息表中找到主机关系对应的每一个对象标签做循环
var text = $(this).text(); #拿到appname
var hid = $(this).attr('hid'); #拿到主机ID
hid_list.push(hid); #将主机ID放入空列表
console.log(hid,text);
})
//console.log(hid_list)
$('#edit_form').find('select').val(hid_list); #将主机列表放到多选框中得到默认选中的选项 });
})
</script>
</html>
Django-website 程序案例系列-7 创建多对多关系表的更多相关文章
- 多对多关系表的创建方式、forms组件
目录 多对多关系表的三种创建方式 1.全自动,Django自动创建 2.纯手撸 3.半自动(推荐使用) forms组件 小例子 forms组件 校验器 钩子函数 局部钩子 全局钩子 forms组件常用 ...
- 用SQLAlchemy创建一对多,多对多关系表
多对多关系表的创建: 如果建立好多对多关系后,我们就可以通过关系名进行循环查找,比如laowang = Teacher.query.filter(Teacher.name=='laowang').fi ...
- Django-website 程序案例系列-18 多表跨表操作优化
详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化 在数据库有外键的时候,使用 select_related() 和 pref ...
- EF架构~关于多对多关系表无法更新与插入的问题
回到目录 在EF里,我们设计模型时,会设计到多对多关系,在EF里会把这种关系会转成两个一对多的关系表,这是比较友好的,因为多对多来说,对于业务本身没什么意思,所以隐藏了,没什么坏处,但对于这个隐藏来说 ...
- 基于.net mvc的校友录(七、文件上传以及多对多关系表的LINQ查询实现)
图片的上传与调用 图片的上传就是文件的上传,在前台使用的是type="file"的input,但是,要将表单声明为multipart/form-data模式,方法是在BeginFo ...
- 多对一关系表 java类描述
少的一方把它查询出来,多的一方看需求把它查出来 涉及java对象涉及到多个对象相互引用,要尽量避免使用一对多,或多对多关系,而应使用多对一描述对象之间的关系(或使用延迟加载的方式). 下个例子empl ...
- Django-website 程序案例系列-17 forms表单验证的字段解释
1.Django内置字段如下: Field required=True, 是否允许为空 widget=None, HTML插件 label=None, 用于生成Label标签或显示内容 initial ...
- Django-website 程序案例系列-16 modle.form(表单验证)
案例程序: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- Django-website 程序案例系列-15 singnal分析
在django框架中singnal的应用相当于在你执行某些重要函数语句时在这条语句的前后放置两个预留的钩子,这两个钩子就是singnal,这个钩子也可以理解成两个触发器,当出现执行语句前后是触发执行某 ...
随机推荐
- 【NOIP2017 D1T3】逛公园
NOIP2017 D1T3 逛公园 题意:给一个有向图,每条边有权值,问从\(1\)到\(N\)的长度不超过最短路长度\(+K\)的路径条数.如果有无数条则输出\(-1\). 思路:我们首先扔掉\(- ...
- ASP.NET Core 防止跨站请求伪造(XSRF/CSRF)攻击 (转载)
什么是反伪造攻击? 跨站点请求伪造(也称为XSRF或CSRF,发音为see-surf)是对Web托管应用程序的攻击,因为恶意网站可能会影响客户端浏览器和浏览器信任网站之间的交互.这种攻击是完全有可能的 ...
- Luogu3825 NOI2017 游戏 2-SAT
传送门 第一眼看上去似乎是一个3-SAT问题 然而\(d \leq 8\)给我们的信息就是:暴力枚举 枚举\(x\)型地图变成\(a\)型地图还是\(b\)型地图(实际上不要枚举\(c\),因为\(a ...
- Codechef MGCHGYM Misha and Gym 容斥、背包、Splay
VJ传送门 简化题意:给定一个长度为\(N\)的数列,\(Q\)个操作: \(1\,x\,a\).将数列中第\(x\)个元素改为\(a\) \(2\,l\,r\).反转子序列\([l,r]\) \(3 ...
- 代码无错就是优?简单工厂模式 C#
还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 现在给你一道面试题,如下: 请用C++,C#,Ja ...
- 蓝牙baseband概述
从蓝牙specispecification中看,基带协议主要分为8个部分来介绍的,分别是概述.物理信道.物理连接.逻辑传输.逻辑连接.封包.比特流的处理.组网行为.这里面会涉及到很多的概念,主要是在概 ...
- cmd命令入门
第一类: 介绍原生的DOS 首先在cmd命令输入help,看到如下图的结果,这里展示的原生的DOS命令. 这里列出了一些命令,可以自己试试的玩.一般看到一个命令后,如果没有说明文档,你就尝试的在其命令 ...
- [UWP 自定义控件]了解模板化控件(7):支持Command
以我的经验来说,要让TemplatedControl支持Command的需求不会很多,大部分情况用附加属性解决这个需求会更便利些,譬如UWPCommunityToolkit的HyperlinkExte ...
- Python下操作Memcache/Redis/RabbitMQ说明
一.MemcacheMemcache是一套分布式的高速缓存系统,由LiveJournal的Brad Fitzpatrick开发,但目前被许多网站使用以提升网站的访问速度,尤其对于一些大型的.需要频繁访 ...
- PHP从入门到精通(三)
PHP数组的分类 按照下标的不同,PHP数组分为关联数组与索引数组: 索引数组:下标从0开始,依次增长:关联数组: 下标为字符串格式,每个下标字符串与数组的值一一关联对应.(有点像对象的键值对) 关于 ...