go操作mysql创建多对多_Django 数据库表多对多的创建和增删改查
前面已經學習了在Django里面如何對單表的操作,同時也學習了1對多(單個外鍵)的表的操作。接下來,我們看看多對多(多個外鍵)的關系如何創建和管理。
比如說,我們有一個主機表,也有一個應用程序表,一個主機可以對應多個程序,一個程序也可以對應多個主機,這是一個典型的多對多的結構。一般來說,我們會在數據庫里創建一個中間的表,分別和這兩個表進行外鍵關聯。
例1. 手動的定義一個HostToApp表,關聯到Host和Application表,這樣一來,如果我希望創建一個新的關聯,我直接對這個中間的表進行操作即可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(to="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='nid')
aobj?=?models.ForeignKey(to='Application',to_field='id')
#創建一個新的關聯關系
HostToApp.objects.create(hobj_id=1,aobj_id=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()
b?=?models.ForeignKey(to="Business",?to_field='id')
class?Application(models.Model):
name?=?models.CharField(max_length=32)
r?=?models.ManyToManyField("Host")
執行manage.py migrate和 manage.py migration 之后,查看數據庫,可以看見自動生成了一個關系表app01_application_r, 里面有3個字段,一個id和兩個外鍵
這個自動生成的表,在Django里面不能直接像單表一樣操作,因為系統并不知道他的‘存在’,因此只能通過間接的操作。
間接操作:
查詢
//這里首先獲取app_id=1的對象,后面的操作都是基于這個前提來的
obj=models.Application.objects.get(id=1)
obj.name
obj.r.all() //類似單表操作
增加
obj.r.add(1) ?//添加app_id=1, host_id=1的記錄
obj.r.add(2,3,4) //直接添加多個值
obj.r.add(*[1,2,3,4]) // 直接通過列表的格式添加多個值
刪除,格式和增加一樣
obj.r.remove(1)
obj.r.remove(2,3)
obj.r.remove(*[2,3,4])
obj.r.clear() //刪除所有app_id=1的關系
修改
obj.r.set([2,3,4]) //直接設置app_id=1, host_id=2,3,4,注意列表前面沒有星號
例3. 下面看個實例
models.pyclass?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(to="Business",?to_field='id')
class?Application(models.Model):
name?=?models.CharField(max_length=32)
r?=?models.ManyToManyField("Host")
urls.py ( 里面有 views.app和 views.ajax_add_app,對比ajax和普通使用)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'^test_ajax$',?views.test_ajax),
url(r'^app$',?views.app),
url(r'^ajax_add_app$',?views.ajax_add_app),
views.py 注意獲取用戶輸入的新的App名稱和這個App所對應的主機列表,分別在不同的表進行創建新數據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)
#直接obj就是創建的新數據的對象
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,主要界面是就是顯示當前數據和一個模態對話框。點擊添加,彈出對話框,然后輸入App和對應的主機名;后臺獲取之后添加返回頁面html>
.host-tag{
display:?inline-block;
padding:?3px;
border:?1px?solid?red;
background-color:?palevioletred;
}
.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?red;
background:?white;
margin-left:?-200px;
}
應用列表
應用名稱應用主機列表
{%?for?app?in?app_list?%}
{{?app.name?}}{%?for?host?in?app.r.all?%}
?{{?host.hostname?}}?
{%?endfor?%}
編輯
{%?endfor?%}
//multiple允許多選,發送到后臺是一個列表,后臺通過get_list接收
{%?for?op?in?host_list?%}
{{?op.hostname?}}
{%?endfor?%}
$(function(){
//顯示對話框
$('#add_app').click(function(){
$('.shade,.add-modal').removeClass('hide');
});
//隱藏對話框
$('#cancel').click(function(){
$('.shade,.add-modal').addClass('hide');
});
//發送一個Ajax請求,序列化的時候,可以直接通過form.serialize(),dataType指定JSON
這樣就不需要獲取之后再做個JSON.parse(data),如果是單個數據,后臺可以直接接收,如果存在列表數據,需要指定tradtional是True
$('#add_submit_ajax').click(function(){
$.ajax({
url:?'/ajax_add_app',
//?data:?{'user':?123,'host_list':?[1,2,3,4]},
data:?$('#add_form').serialize(),
type:?"POST",
dataType:?'JSON',?//?內部
traditional:?true,
success:?function(obj){
console.log(obj);
},
error:?function?()?{
}
})
});
})
結果如下所示:
在我們使用模態對話框的時候,使用AJAX的好處是可以實現一些驗證的功能;如果我們不在同一個Url里面使用模態對話框,而是新開一個URL來創建數據,可以直接用普通的form提交就行了。模態對話框適合小數據的提交,而新的Url更適合大量數據的提交(比如新開一個頁面寫博客)
總結
以上是生活随笔為你收集整理的go操作mysql创建多对多_Django 数据库表多对多的创建和增删改查的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 力控批量建立数据库点参数操作
- 下一篇: 南方cass字体样式设置_实用|史上最全
