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和两个外键

fc628bddaf1e3b49d7fa8aa1e0662211.png

这个自动生成的表,在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 () {

}

})

});

})

结果如下所示:

4cf2e8682e46f7693b1a6f4af7001384.png

e212506473d9a1946ac8ac25937972fe.png

e9c91c1af3bf5f7ceb0c080be1bbb876.png

在我们使用模态对话框的时候,使用AJAX的好处是可以实现一些验证的功能;如果我们不在同一个Url里面使用模态对话框,而是新开一个URL来创建数据,可以直接用普通的form提交就行了。模态对话框适合小数据的提交,而新的Url更适合大量数据的提交(比如新开一个页面写博客)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/417368.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VMware 报错“Intel VT-x处于禁止状态”

VMware Workstation 10虚拟机安装64位windows server 2008 R2系统时报错“Intel VT-x处于禁止状态”,如下图。 工具/原料 VMware Workstation 10 32位windows server 2008 R2 64位方法/步骤 重启电脑,启动中按F1键进入BIOS。(电脑不同进入BIOS的按键不同…

C# CKEditor、CKFinder集成使用

1.裁剪&#xff08;ckeditor在\_Samples\ckeditor中&#xff09;2.添加引用&#xff1a;CKEditor.NET.dll、CKFinder.dll3.配置CKEditor&#xff1a;ckeditor/config.jsCKEDITOR.editorConfig function (config) {config.skin office2003;};4.使用CKEditor&#xff1a;<% …

tcp/ip四层和osi七层

转载于:https://www.cnblogs.com/mountian-lion/p/6353819.html

Shell 自定义函数

语法&#xff1a; function fname() { 程序段} 例子&#xff1a; #!/bin/bash## 定义函数,分子除以分母&#xff0c;算利润、占有率等## 参数1&#xff1a;分子## 参数2&#xff1a;分母function divfun() {## 参数判断,需要输入两个参数 if [ $# -ne 2 ];thenecho "Enter…

java kafka 集群消费_kafka集群简单生产者消费者实例

项目描述本项目是个简单的kafka集群简单生产者和消费者实例&#xff0c;生产者能生产消息&#xff0c;消费者能消费消息&#xff0c;这里将消费的消息存入了mysql数据库&#xff0c;适合刚kafka刚入门的朋友借鉴使用&#xff0c;里面的zookeeper集群和kafka集群的地址需要修改为…

EJB是什么?EJB的概念分析与理解(copy)

【说明&#xff1a;转载于http://blog.csdn.net/jojo52013145/article/details/5783677】 1. 我们不禁要问&#xff0c;什么是"服务集群"&#xff1f;什么是"企业级开发"&#xff1f; 既然说了EJB 是为了"服务集群"和"企业级开发"&…