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

我想使用第一个例子。由于书籍没有通用页面。要将书籍连接到页面,您必须使用向后关系。在此关系中,使用_set方法。所有型号名称和归档名称必须为小写字母,尽管它们是大写字母。

m=book.page_set.all()

现在,您可以使用m使用"书籍中的页面"的所有属性。 有关反向或反向关系的更多信息,请访问此处

在您的视图中,您可以传递书籍的 ID,并在查询中使用它来过滤它们链接到它的页面。

例如:

def show_pages(request, book_id):
pages = Pages.objects.filter(book=book_id)

最新更新