博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django 数据库表多对多的创建和增删改查
阅读量:6841 次
发布时间:2019-06-26

本文共 4454 字,大约阅读时间需要 14 分钟。

前面已经学习了在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.py

    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")

urls.py ( 里面有 views.app和 views.ajax_add_app,对比ajax和普通使用)

from django.conf.urls import urlfrom django.contrib import adminfrom app01 import viewsurlpatterns = [    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和对应的主机名;后台获取之后添加返回页面

    
    
    
    

应用列表

     
        
    
    
                                    应用名称                应用主机列表                                        {% 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 %}                                        
            
                    
    

结果如下所示:

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

转载地址:http://njbul.baihongyu.com/

你可能感兴趣的文章
Spring高级应用之注入嵌套Bean
查看>>
mini6410 uboot1.1.6 MMC fat command support
查看>>
系统日志的实践应用
查看>>
基于SmartGwt的分页组件
查看>>
【oraInventory】由OUI-10035和OUI-10033错误引发的关于oraInventory目录位置的思考
查看>>
网站访问用时统计
查看>>
小技巧--sendmail脚本
查看>>
何时需要权衡可见性
查看>>
Cocos2d-x 3.x游戏开发之旅
查看>>
JavaWeb技术之--面向对象设计模式
查看>>
EKL PHP 调取_search接口查询 添加购物车统计
查看>>
linux 查看IO情况
查看>>
序列化 serialize 问题
查看>>
【shell】Linux shell 之 case 详解
查看>>
人生是什么?
查看>>
Ant 给工程打包
查看>>
test.log文件传输到另一台服务器上 --rsync
查看>>
Widgets must be created in the GUI thread
查看>>
JQuery Highcharts图表控件使用说明
查看>>
python基础教程
查看>>