博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

django的models中一对多和多对多

Posted on 2023-04-11 10:22  心默默言  阅读(50)  评论(0编辑  收藏  举报

我有四个对像:作者,作者详情,出版社,书籍,那关系模型建模

1、作者和作者详情,这个不用说,一定是一对一关系

2、作者和书籍,一个作者可以出多本书,一本书可以有多个作者,那就是多对多关系

3、出版社和书籍,一个出版社可以出多个书籍,那就是一多对多关系

 

 

创建表格

# Create your models here.
class Author(models.Model):
    author_name = models.CharField(max_length=8, null=False)


class AuthorDetail(models.Model):
    author_sex = models.IntegerField(choices=((0, ""), (1, "")), null=False)
    author_phone = models.CharField(max_length=11, null=False)
    author_age = models.IntegerField(null=False)
    # 一对一关系的两个类,关系模型写到哪个类里都行,但是代码是顺序执行的,如果放在第一个类,在执行
    # 到对应表格时,还没有创建,所以要写到第二个类里
    # models.CASCADE是级联删除,即关系方数据删掉,本表的相关信息也一并删掉,可参考前面的外键博客
    author = models.OneToOneField(to=Author, to_field="id", on_delete=models.CASCADE)


class Publisher(models.Model):
    publisher_name = models.CharField(max_length=30, null=False)
    publisher_address = models.CharField(max_length=50, null=False)
    publisher_city = models.CharField(max_length=30, null=False)
    publisher_website = models.URLField(null=True)


class Book(models.Model):
    book_name = models.CharField(max_length=20, null=False)
    # 多对多关系与一对一关系同理,写到哪个都行,也是顾及代码执行顺序,要写到下面的类里
    author = models.ManyToManyField(to=Author)
    # 一对多关系,要写到多的类里
    publisher = models.ForeignKey(to=Publisher, to_field="id", on_delete=models.CASCADE)
    price = models.FloatField(max_length=6, null=None)
一对多和多对多
 

1.增加一条数据

In [2]:
from main_test.db_manager.models import Author
#单表增加
Author.objects.create(author_name="老虎")
Out[2]:
<Author: Author object (1)>
In [3]:
#一多对关系:先查询外键对像,再增加
from main_test.db_manager.models import AuthorDetail

author = Author.objects.filter(author_name="老虎").first()
AuthorDetail.objects.create(author=author, author_phone="15010133434", author_age=24, author_sex=0)
Out[3]:
<AuthorDetail: AuthorDetail object (1)>
In [7]:
from main_test.db_manager.models import Publisher,Book

publisher1  = Publisher.objects.create(publisher_name="上海大学出版社",publisher_address="陆家嘴",publisher_city="上海",publisher_website="http://nihao.com")
In [10]:
#多对多关系:
publisher2  = Publisher.objects.get(publisher_name="上海大学出版社")
In [13]:
author = Author.objects.get(author_name="老虎")
book = Book.objects.create(publisher=publisher2,book_name="你好未来2",price=35.5)
In [14]:
book.author.add(author)
 

以下会报错 author = Author.objects.get(author_name="老虎") book = Book.objects.create(publisher=publisher2,book_name="你好未来3",price=35.5,author=author)

 

2.查询数据

In [17]:
#单个表格查询
Author.objects.filter(author_name="老虎").first()
Out[17]:
<Author: Author object (1)>
In [18]:
Author.objects.get(author_name="老虎")
Out[18]:
<Author: Author object (1)>
 

get 和 filter的区别
get:返回一个对像,数据库只能有一条对像,如果查询出多条或者没有会报错;
filter:返回一个列表,数据库没有会返回长度是0的列表,所以在调用列表里某个对像时,应当像列表一样加个脚标,first()是取列表中第一个对像的意思.

 

一对多关系查询

In [23]:
author_detail=Author.objects.filter(author_name="老虎").first().authordetail #正像查询
In [24]:
author_detail.author_phone
Out[24]:
'15010133434'
In [26]:
AuthorDetail.objects.filter(id=1).first().author #返向查询
Out[26]:
<Author: Author object (1)>
 

多对多关系查询

In [28]:
book = Book.objects.filter(book_name="你好未来",id=1).first()
book.book_name
Out[28]:
'你好未来'
In [29]:
author = book.author.all()
author
Out[29]:
<QuerySet [<Author: Author object (1)>]>
 

修改数据

In [30]:
#修改一个值:先查询再修改
Author.objects.filter(author_name="老虎").update(author_name ="毛毛")
Out[30]:
1
 

删除:先查询,再删除

In [31]:
author = Author.objects.filter(author_name="毛毛").first()
author.delete()
Out[31]:
(4,
 {'db_manager.AuthorDetail': 1,
  'db_manager.Book_author': 2,
  'db_manager.Author': 1})