Django 模型层之多表操作

Posted louyefeng

tags:

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

一.创建模型

实例:

作者表:
    拥有字段:姓名(name),性别(sex),该表与书籍表之间为多对多的关系
作者详情表:
    拥有字段:地址(addr),手机号(phone),该表与作者表之间为一对一的关系
出版社表:
    拥有字段:名字(name),地址(addr),该表与书籍表之间为一对多的关系
书籍表:
    拥有字段:书名(name),单价(price)
分析:一本书可以拥有多个作者,一个作者可以写多本书,所有作者与书籍之间为多对多的关联关系(Many-To-Many);一本书只有一个出版社,但是一个出版社可以出版多种书籍,所以出版社和书籍之间是一对多的关联关系(One-To-Many);作者与作者详情就是一对一关联关系(One-To-One)

所以在Models.py下创建模型如下

class Publish(models.Model):
    name = models.CharField(max_length=255)
    addr = models.CharField(max_length=255)

    def __str__(self):
        return self.name


class Author(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    sex = models.IntegerField()
    authordetail = models.OneToOneField(to='AuthorDetail')

    def __str__(self):
        return self.name


class AuthorDetail(models.Model):
    id = models.AutoField(primary_key=True)
    addr = models.CharField(max_length=255)
    phone = models.CharField(max_length=255)


class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    # 外键,关联关系写在一对多中多的那一方
    publish = models.ForeignKey(to=Publish)
    authors = models.ManyToManyField(to=Author)

    def __str__(self):
        return self.name

注意事项:

1.id字段不写的话会自动添加
2.对于外键字段,Django会在字段名上添加"_id"来创建数据库中的列名
3.外键字段ForeignKey有一个null=True的设置,你可以赋给它空值None

二.添加表记录

一对一:

# 方式一:
detail_obj = models.AuthorDetail.objects.filter(id=2).first()
models.Author.objects.create(name='Yven',sex=1,authordetail=detail_obj)

# 方式二:
models.Author.objects.create(name='hwt',sex=2,authordetail_id=1)

一对多:

# 方式一:
publish_obj = models.Publish.objects.filter(id=2).first()
models.Book.objects.create(name='水浒传',price=24.5,publish=publish_obj)

# 方式二:
models.Book.objects.create(name='西游记',price=24.5,publish_id=2)

多对多:

# 获得书籍对象
book = models.Book.objects.create(name='水浒传',price=24.5,publish_id=3)
# 获得作者对象
yven = models.Author.objects.get(name='Yven')
hwt = models.Author.objects.get(name='hwt')

# 绑定多对多关系
# add中可以传递对象,可以传递id,也可以传递*列表如:(*[yven,hwt])
book.authors.add(yven,hwt)

#多对多关系其他常用API:
# 将某个特定的对象从被关联对象集合中去除,可以传递对象,可以传递id,也可以传递*列表如:(*[yven,hwt])
book.authors.remove()
# 清空被关联对象集合,无需传参
book.authors.clear()
# 先清空再设置,传递的参数必须是可迭代对象,一般为列表,列表内可以是对象,也可以是id
book.authors.set()

三.基于对象的跨表查询

一对一查询

正向查询(按字段:authordetail)

# 查询作者姓名为Yven的手机号
yven = models.Author.objects.get(name='Yven')
phone = yven.authordetail.phone

反向查询(按表名小写:author)

# 查询手机号为12221321的作者名
authordetail = models.Author.objects.filter(phont='12221321').first()
name = authordetail.author.name

一对多查询

正向查询(按字段:publish)

# 查询西游记的出版社名
book = models.Book.objects.filter(name='西游记').first()
name = book.publish.name

反向查询(按表名小写_set.all():book_set.all())

# 查询pk为2的出版社出版书籍的单价
publish = models.Publish.objects.filter(pk='2').first()
booklist = publish.book_set.all() #QuerySet对象
for obj in booklist:
    print(obj.price)

多对多查询

正向查询(按字段.all():publish.all())

# 查询水浒传的所有作者
book = models.Book.objects.get(name='水浒传')
author = book.authors.all()
for i in author:
    print(i.name)

反向查询(按表名小写_set.all():book_set.all())

# 查询Yven写的多少有书籍的单价
author = models.Author.objects.get(name='Yven')
book = author.book_set.all()
for i in book:
    print(i.price)

四.基于双下划线的跨表查询

Django还提供了一种直观而搞笑的方式在查询(lookups)种表示关联关系,它能自动确认SQL JOIN联系。要做跨关系查询,就使用两个下划线来连接模型(model)间关联字段的名称,知道最终链接到你想要的model为止。

一对一查询

正向查询(按字段):authordetail

# 查询Yven的地址
models.Author.objects.filter(name='Yven').values('authordetail__addr')

反向查询(按表名):author

# 查询Yven的地址
models.AuthorDetail.objects.filter(author__name='Yven').values('addr')

一对多查询

正向查询(按字段):publish

# 查询西游记的出版社名
models.Book.objects.filter(name='西游记').values('publish__name')

反向查询(按表名):book

# 查询西游记的出版社名
models.Publish.objects.filter(book__name='西游记').values('name')

多对多查询

正向查询(按字段):authors

# 查询水浒传的作者性别
models.Book.objects.filter(name='水浒传').values('authors__sex')

反向查询(按表名):book

# 查询水浒传的作者性别
models.Author.objects.filter(book__name='水浒传').values('sex')

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

Django 模型层之多表操作

Django之路

django目录

django之多表查询

django之多表查询操作

django之多表操作