day19-创建多对多以及增加示例

一、前言

之前我们说的都是orm都是一对多,今天我们来了解一下多对多关系,比如说一台主机上有多个应用,一个应用可以部署在多台主机上,类似这种情况的,多对多关系的。那我们怎么设计的表结构,那在django框架里面,这个多对多是如何建立的呐?下面我们就来学习一下。

二、创建多对多的方式

2.1、建立的多对多表关系

2.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()

class Application(models.Model):
    name = models.CharField(max_length=32)

class HostToApp(models.Model):  #手动创建第三张表
    host = models.ForeignKey(to="Host",to_field="nid",on_delete=models.CASCADE,)
    application = models.ForeignKey(to="Application",to_field="id",on_delete=models.CASCADE,)

增加数据类似于:

HostToApp.objects.create(host_id=1,application_id=2)

2.3、自动创建关系表

说明:是第三张表关系是django自动帮我我们创建的,不需要自己去创建

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()
    business = models.ForeignKey(to="Business",to_field="id",on_delete=models.CASCADE,)

class Application(models.Model):
    name = models.CharField(max_length=32)
    host = models.ManyToManyField(to="Host") #自动创建第三张表

数据库表结构生成第三表:

我因为是用内部创建的表,是无法通过类去操作数据库的,因为你看不到,所以,就用  host 这个多对多的关系字段,这个字段就相当于暴露一根线,通过它对第三张表进行操作,操作如下:

①添加(add)

obj = Application.objects.get(id=1)
obj.name #获取name字段的值

obj.host.add(2)  #增加一个application_id=1,host_id=2的值
obj.host.add(1,2,3) #增加application_id=1,host_id=1的值,application_id=1,host_id=2的值,application_id=1,host_id=3的值
obj.host.add(*[1,2,3]) #增加多个关系,可以传入一个列表,和上面一样

②删除(remove)

obj = Application.objects.get(id=1)
obj.name #获取name字段的值

obj.host.remove(2)  #删除一个application_id=1,host_id=2的值
obj.host.remove(1,2,3) #删除application_id=1,host_id=1的值,application_id=1,host_id=2的值,application_id=1,host_id=3的值
obj.host.remove(*[1,2,3]) #删除多个关系,可以传入一个列表,和上面一样

③清除(clear)

obj = Application.objects.get(id=1)

obj.host.clear()  #清除application_id=1的所有数据记录

④ 设置(set)

obj = Application.objects.get(id=1)
obj.host.set([1,3])  #这边列表前面没有*,数据库只保存host_id=1,application_id=1;host_id=1,application_id=3的数据,其他的全部清除

⑤获取另外一张表(Host)符合条件的对象

说明:拿到的是QuerySet类型的,里面是另外一张表(Host)的对象

obj = Application.objects.get(id=1)
# Application.objects后面能加什么,obj.host后面就能加什么
obj.host.all()  #application_id对应的host_id有10个,那么就会把符合条件的Host对象全部拿到,也就是说所有相关主句对象'列表'

如图:

三、增加示例

3.1、正常的form表单提交

1、urls.py的增加

说明:增加一个url,这个url叫app

from django.urls import path,re_path
from app01 import views

urlpatterns = [
    re_path('^app/$',views.app)
]

2、templates用form提交方式:

 1 <head>
 2     <meta charset="UTF-8">
 3     <title>Title</title>
 4     <style>
 5         .host-tag{
 6             display: inline-block;
 7             padding: 3px;
 8             border: 1px solid red;
 9             background-color: palevioletred;
10         }
11         .hide{
12             display: none;
13         }
14         .shade{
15            position: fixed;
16             top:0;
17             right:0;
18             left:0;
19             bottom: 0;
20             background: black;
21             opacity: 0.6;
22             z-index: 100;
23         }
24         .add-modal{
25             position: fixed;
26             height: 300px;
27             width: 400px;
28             top:200px;
29             left: 50%;
30             z-index: 101;
31             border: 1px solid white;
32             background: white;
33             margin-left: -200px;
34         }
35     </style>
36 </head>
37 <body>
38     <h1>应用列表</h1>
39     <div>
40         <input id="add_host" type="button" value="添加"/>
41     </div>
42     <table border="1">
43         <thead>
44             <tr>
45                 <td>应用名称</td>
46                 <td>应用主机列表</td>
47             </tr>
48         </thead>
49         <tbody>
50             {% for app in app_list %}
51                 <tr>
52                     <td>{{ app.name }}</td>
53                     <td>
54                         {% for host in app.host.all %}
55                             <span class="host-tag">{{ host.hostname }}</span>
56                         {% endfor %}
57                      </td>
58                 </tr>
59             {% endfor %}
60         </tbody>
61     </table>
62     <div class="shade hide"></div>
63     <div class="add-modal hide">
64         <form id="add_form" method="post" action="/app/">
65             <div class="group">
66                 <input id="app_name" type="text" placeholder="应用名称" name="app_name">
67             </div>
68             <div class="group">
69                 <select id="sel" name="host_list" multiple>
70                     {% for op in host_list %}
71                         <option value="{{ op.nid }}">{{ op.hostname }}</option>
72                     {% endfor %}
73                 </select>
74             </div>
75             <input type="submit" value="提交">
76             <input id="cancel" type="button" value="取消">
77         </form>
78     </div>
79 
80     <script src="/static/jquery-1.12.4.js"></script>
81     <script>
82         $(function(){
83             $("#add_host").click(function(){
84                 $(".shade,.add-modal").removeClass("hide");
85             });
86 
87             $("#cancel").click(function(){
88                 $(".shade,.add-modal").addClass("hide");
89             });
90         })
91     </script>
92 </body>
app.html

3、view.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")
        print(app_name,host_list,sep="\t")
        #创建完了,会返回一个对象,这个对象就是你刚增加完的这条数据的对象
        obj = models.Application.objects.create(name=app_name)
        obj.host.add(*host_list)
        return redirect("/app/")

3.2、用ajax方式提交

说明:这边我提交到一个行的url上去,跟上面区别开来

1、urls.py的代码

from django.urls import path,re_path
from app01 import views

urlpatterns = [
    re_path('^ajax_add_app/$',views.ajax_add_app)
]

2、templates用ajax提交方式:

  1 <head>
  2     <meta charset="UTF-8">
  3     <title>Title</title>
  4     <style>
  5         .host-tag{
  6             display: inline-block;
  7             padding: 3px;
  8             border: 1px solid red;
  9             background-color: palevioletred;
 10         }
 11         .hide{
 12             display: none;
 13         }
 14         .shade{
 15            position: fixed;
 16             top:0;
 17             right:0;
 18             left:0;
 19             bottom: 0;
 20             background: black;
 21             opacity: 0.6;
 22             z-index: 100;
 23         }
 24         .add-modal{
 25             position: fixed;
 26             height: 300px;
 27             width: 400px;
 28             top:200px;
 29             left: 50%;
 30             z-index: 101;
 31             border: 1px solid white;
 32             background: white;
 33             margin-left: -200px;
 34         }
 35     </style>
 36 </head>
 37 <body>
 38     <h1>应用列表</h1>
 39     <div>
 40         <input id="add_host" type="button" value="添加"/>
 41     </div>
 42     <table border="1">
 43         <thead>
 44             <tr>
 45                 <td>应用名称</td>
 46                 <td>应用主机列表</td>
 47             </tr>
 48         </thead>
 49         <tbody>
 50             {% for app in app_list %}
 51                 <tr>
 52                     <td>{{ app.name }}</td>
 53                     <td>
 54                         {% for host in app.host.all %}
 55                             <span class="host-tag">{{ host.hostname }}</span>
 56                         {% endfor %}
 57                      </td>
 58                 </tr>
 59             {% endfor %}
 60         </tbody>
 61     </table>
 62     <div class="shade hide"></div>
 63     <div class="add-modal hide">
 64         <form id="add_form">
 65             <div class="group">
 66                 <input id="app_name" type="text" placeholder="应用名称" name="app_name">
 67             </div>
 68             <div class="group">
 69                 <select id="sel" name="host_list" multiple>
 70                     {% for op in host_list %}
 71                         <option value="{{ op.nid }}">{{ op.hostname }}</option>
 72                     {% endfor %}
 73                 </select>
 74             </div>
 75             <input id="add_submit_ajax" type="button" value="ajax提交">
 76             <input id="cancel" type="button" value="取消">
 77         </form>
 78     </div>
 79 
 80     <script src="/static/jquery-1.12.4.js"></script>
 81     <script>
 82         $(function(){
 83             $("#add_host").click(function(){
 84                 $(".shade,.add-modal").removeClass("hide");
 85             });
 86 
 87             $("#cancel").click(function(){
 88                 $(".shade,.add-modal").addClass("hide");
 89             });
 90             $("#add_submit_ajax").click(function(){
 91                 $.ajax({
 92                 url:'/ajax_add_app/',
 93                 data:$("#add_form").serialize(),
 94                 type:"POST",
 95                 dataType:"JSON",//在jquery内部帮你做序列化的处理,代替了success里面的JSON.parse(data)这一步
 96                 traditional: true, //{'host_list':[1,2,3,4]},jquery内部帮你做处理,可是它处理不了,发到后台是none,所以这边要告诉jquery需要处理
 97                 success: function(obj){ //这样的话,这边就不是data了,而是obj对象
 98                     if(obj.status){
 99                         location.reload()
100                     }else {
101                         console.log(obj.error)
102                     }
103                 },
104                 error: function(){
105                     //发送一个请求,后台没有捕捉到的,发生了一个未知的问题
106                 }
107             })
108             });
109         })
110     </script>
111 </body>
app.html

3、view.py代码:

def ajax_add_app(request):
    import json
    ret = {'status':True,'error':None,'data':None}
    print(request.POST)
    app_name = request.POST.get("app_name")
    host_list = request.POST.getlist("host_list")
    print(app_name,host_list)
    obj = models.Application.objects.create(name=app_name)  #创建完了,会返回一个对象,这个对象就是你刚增加完的这条数据的对象
    obj.host.add(*host_list)
    return  HttpResponse(json.dumps(ret))

四、总结

4.1、ajax提交方式

$.ajax({
url:'URL',
data:$("#id").serialize(),
type:"POST",
dataType:"JSON",//在jquery内部帮你做序列化的处理,代替了success里面的JSON.parse(data)这一步
traditional: true, //{'host_list':[1,2,3,4]},jquery内部帮你做处理,可是它处理不了,发到后台是none,所以这边要告诉jquery需要处理
success: function(obj){ //这样的话,这边就不是data了,而是obj对象
    if(obj.status){
        location.reload()
    }else {
        console.log(obj.error)
    }
},
error: function(){
    //发送一个请求,后台没有捕捉到的,发生了一个未知的问题
}
})

4.2、创建多对多

host = models.ManyToManyField(to="Host")

4.3、创建第三张表数据

obj = models.Application.objects.create(name=app_name)  #创建时候,返回你创建那条数据的对象
obj.host.add(*host_list) #通过这个对象去创建第三张表的数据

4.4、创建多对关系哪种方式好?

答:我觉得方式一比较好,①方式二只能帮你3列,不能创建5列,6列,加额外的数据,它做不到。②方式一:想加几列加几列,可以自定义话。

4.5、编辑数据

obj = models.Application.objects.get(id=1)
obj.name = "new_name"
obj.save()  #不管多对多还是一对多,更新数据都需要这种方式

obj.host.set([1,2,3,4])  #更新第三张表需要用到set

 

转载于:https://www.cnblogs.com/zhangqigao/articles/8619163.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值