django的多表操作

Posted huang-yc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django的多表操作相关的知识,希望对你有一定的参考价值。

django的多表操作

1.使用场景

在实际生产过程多,我们面对的数据纷繁复杂,此时就需要良好的数据结构设计,多表之间的约束关系为我们提供了数据管理以及查询的便利。在mysql中我们利用外键(foreign key)来实现这样的约束关系,在django中我们通过调用相应的API来实现这样的功能。

2.创建模型

实例:我们来假定下面这些概念,字段和关系

  • 作者模型:一个作者有姓名和年龄。作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

 

  • 出版商模型:出版商有名称,所在城市以及email。
  • 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);
  • 一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)

模型建立的代码(module)如下:

技术分享图片
 1 from django.db import models
 2 # Create your models here.
 3 
 4 class Author(models.Model):
 5     nid = models.AutoField(primary_key=True)
 6     name=models.CharField( max_length=32)
 7     age=models.IntegerField()
 8 
 9     # 与AuthorDetail建立一对一的关系
10     authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
11 
12 class AuthorDetail(models.Model):
13 
14     nid = models.AutoField(primary_key=True)
15     birthday=models.DateField()
16     telephone=models.BigIntegerField()
17     addr=models.CharField( max_length=64)
18 
19 class Publish(models.Model):
20     nid = models.AutoField(primary_key=True)
21     name=models.CharField( max_length=32)
22     city=models.CharField( max_length=32)
23     email=models.EmailField()
24 
25 class Book(models.Model):
26 
27     nid = models.AutoField(primary_key=True)
28     title = models.CharField( max_length=32)
29     publishDate=models.DateField()
30     price=models.DecimalField(max_digits=5,decimal_places=2)
31 
32     # 与Publish建立一对多的关系,外键字段建立在多的一方
33     publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
34     # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表
35     authors=models.ManyToManyField(to=Author,)
View Code

 

在MYSQL生成的表如下:

技术分享图片

 

注意事项:

  • 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
  • id 字段是自动添加的
  • 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
  • 这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
  • 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
  • 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None

 

3.添加表数据

在进行多表操作前,先创建一些基础的表数据:

publish表:

技术分享图片

authordetail表:

技术分享图片

author表:

技术分享图片

3.1 一对多

book就是一对多的例子:

技术分享图片
方式1:
   publish_obj=Publish.objects.get(nid=1)
   book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish=publish_obj)

方式2:
   book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish_id=1)
View Code

 

 技术分享图片

3.2 多对多

技术分享图片
# 当前生成的书籍对象
    book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1)
    # 为书籍绑定的做作者对象
    yuan=Author.objects.filter(name="yuan").first() # 在Author表中主键为2的纪录
    egon=Author.objects.filter(name="alex").first() # 在Author表中主键为1的纪录

    # 绑定多对多关系,即向关系表book_authors中添加纪录
    book_obj.authors.add(yuan,egon)    #  将某些特定的 model 对象添加到被关联对象集合中。   =======    book_obj.authors.add(*[])
View Code

 

 数据库表纪录生成如下:
book表

技术分享图片

book_authors表

技术分享图片

核心:book_obj.authors.all()是什么?
多对多关系其它常用API

book_obj.authors.remove()      # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear()       #清空被关联对象集合
book_obj.authors.set()         #先清空再设置

 test

以上是关于django的多表操作的主要内容,如果未能解决你的问题,请参考以下文章

第十二章 ORM的多表操作

Django-orm:单表查询基于对象和双下划线的多表操作集合查询分组查询F查询和Q查询

服务后端Django的多表数据查询

mybatis-基于xml的多表查询

Django DRF序列化器或视图中的多表过滤

ORM的多表查询详述