python - Django 模型 - 一对多或多对多
问题描述
在 Django 中没有一对多关系,只有多对一。如果在子表上定义外键很奇怪,我们应该选择多对多吗?
例如:
书有很多页。如果我们在 Page 模型上定义外键,那么该页面就有一本书,这不是一件直观的事情(或说)。
选项1:
class Book(models.Model):
name = models.CharField(max_length=100)
date_published = models.DateTimeField(default=timezone.now)
class Page(models.Model):
page_number = models.IntegerField()
page_text = RichTextField()
book = models.ForeignKey(Book, on_delete=models.CASCADE)
选项 2
class Book(models.Model):
name = models.CharField(max_length=100)
date_published = models.DateTimeField(default=timezone.now)
pages = models.ManytoMany(Page)
class Page(models.Model):
page_number = models.IntegerField()
page_text = RichTextField()
在选项 2 中,我可以通过 book.pages 访问本书的页面。
在选项 1 中,我不知道如何访问这些页面,也许 book.pages_set.objects.all() 并不漂亮。
我问了一位程序员,他说只使用多对多。我了解每种方法的含义,并且我也了解两者之间在数据库中发生的情况的区别。我的问题是什么是更好/标准的方法。
解决方案
我赞成第一个选项,因为许多书籍没有公共页面及其包含。因此,使用第一个选项,您可以使用以下查询集访问书页
pages = book.page_set.all()
在这里,您还可以在外键字段中使用 related_name 参数:
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name="pages")
然后可以使用来获取书页
pages = book.pages.all()
推荐阅读
- python - Python:递归地将字典附加到另一个
- node.js - 赫罗库 | 不能获取
- concurrency - ConcurrentHashMap::computeIfAbsent 是每个键还是每个 ConcurrentHashMap 的原子?
- firebase - 如何在 Firebase 中使用私人帐户实现追随者系统?
- python - 如何使用 for 循环简化 lst = [ x**2 for x in [x**2 for x in range(11)]] 此代码
- c++ - Win32 api中的画笔
- java - androidx.appcompat.widget.AppCompatEditText 错误
- javascript - Dropbox API Javascript - uploadFile() 导致 400 错误请求
- sql - 谈 ANSI SQL 时,JOIN 和 LEFT JOIN 有区别吗?
- r - 闪亮的应用程序错误无法将类型“环境”强制转换为“字符”类型的向量