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,一经查实,立即删除!

相关文章

SQL Server 日志清理、数据文件收缩

use DBNameDUMP TRANSACTION DBName WITH NO_LOG BACKUP LOG DBName WITH NO_LOGDBCC SHRINKFILE (DBName, 1);--收缩数据库DBCC SHRINKFILE (DBName_Log, 1);--收缩日志

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的按键不同…

IIS 指定了身份验证方案“IntegratedWindowsAuthentication, Anonymous”,但绑定仅支持一种身份验证的规范。...

IIS 指定了身份验证方案“IntegratedWindowsAuthentication, Anonymous”,但绑定仅支持一种身份验证的规范。有效的身份验证方案为摘要、协商、NTLM、基本或匿名。请更改 IIS 设置,以便仅使用单一的身份验证方案。 错误提示说得很明白:IIS要么…

java u003_我在B站学编程 DAY-003 JAVA基础概念和语法

八进制:0-7组成例子:八卦指令在机器中以机器码格式输出,机器码一次原始输出位数是八的倍数,即以字节长度为最小单位输出。十六进制:0-9,abcde...组成,0X开头十六进制可以更紧凑地表示二进制&…

win7 64安装工商网银U盾软件

采用分步安装即可: 下载安装安全控件安装证书驱动程序

[大数据可视化]-saiku的源码包Bulid常见问题和jar包

最近在做kylinmondriansaiku的二次开发的时候,Bulid saiku的源码出现了很多问题,基本上一大部分问题jar找不到问题,很多jar国内网站都找不到。这时候只有手动下载然后注册到MAVEN本地仓库中去。 我把这些包放上来希望对给需要的朋友一些帮助。…

java 计算工具类_java精确计算工具类

importjava.math.BigDecimal;importjava.math.RoundingMode;importjava.math.BigDecimal;importjava.text.DecimalFormat;importorg.springframework.stereotype.Component;/*** 工具类 - 运算*/Componentpublic classArithUtils {//默认除法运算精度private static final int …

win7 64 安装sp1补丁提示“客户端没有所需的特权”

右击以管理员身份运行,再就是在控制面板,用户账户和家庭安全,用户账户,更改用户账户控制设置,调到最低。 重新启动电脑即可运行。

C# 全角半角相互转换

/// <summary>/// 半角转全角(SBC case)/// 全角空格为12288&#xff0c;半角空格为32/// 其他字符半角(33-126)与全角(65281-65374)的对应关系是&#xff1a;均相差65248/// </summary>/// <param name"input">任意字符串</param>/// <r…

java进程和线程_Java™ 教程(进程和线程)

并发计算机用户想当然地认为他们的系统一次可以做不止一件事&#xff0c;他们设想他们可以继续在文字处理器中工作&#xff0c;而其他应用程序则下载文件、管理打印队列和流音频&#xff0c;即使是单个应用程序通常也希望一次完成多个任务。例如&#xff0c;流式音频应用程序必…

C++ 中关于optional 使用过程中遇到的问题

头文件&#xff1a;#include <boost/optional.hpp> using namespace boost; optional很像一个仅能存放一个元素的容器&#xff0c;它实现了"未初始化"的概念&#xff1a;如果元素未初始化&#xff0c;那么容器就是空的&#xff0c;否则&#xff0c;容器内就是有…

java config 类_Spring ----JavaConfig类代替XML配置Bean

1.使用JavaConfig实现Bean对象创建&#xff1a;通过Spring ApplicationContext的另一个容器AnnotationConfigurationApplicationContext的实现类ApplicationContext ac  new AnnotationConfigurationApplicationContext(“包名|配置类|bean工厂&#xff1f;”) 依赖工厂&a…

SQLServer 生成当前日期备份

DECLARE DataBase NVARCHAR(64)DECLARE strDate NVARCHAR(64)DECLARE strPath NVARCHAR(512)--备份采集配置数据库use TestDBSET DataBaseTestDBset strPathE:\数据库备份\set strDate convert(NVARCHAR(19),getdate(),120)set strDate REPLACE(strDate, : , )set strDate R…

白话经典算法系列之一 冒泡排序的三种实现

http://blog.csdn.net/morewindows/article/details/6657829 冒泡排序是非常容易理解和实现&#xff0c;&#xff0c;以从小到大排序举例&#xff1a; 设数组长度为N。 1&#xff0e;比较相邻的前后二个数据&#xff0c;如果前面数据大于后面的数据&#xff0c;就将二个数据交…