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>