Django模型(继承、一对多、多对多)

Posted

技术标签:

【中文标题】Django模型(继承、一对多、多对多)【英文标题】:Django model (inheritence, one-to-many, many-to-many) 【发布时间】:2020-05-04 09:02:18 【问题描述】:

models.py

from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _


class Book(models.Model):

    class TYPE_OF_BOOK(models.TextChoices):
        COMPUTER = 'COM', _('Computer')
        NATURAL_SCIENCE = 'NAT', _('Natual_Science')
        ECONOMY = 'ECO', _('ECONOMY')
        HISTORY = 'HIS', _('History')

    type_of_book = models.CharField(
        max_length=10,
        choices=TYPE_OF_BOOK.choices,
        default=True,
   )

    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    published_date = models.DateField(blank=True)

    def __str__(self):
        return self.title

class Review(models.Model):
   book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name='reviews')
    author = models.CharField(max_length=50)
    text = models.TextField()
    grade = models.IntegerField(default=5)
    created_date = models.DateTimeField(default = timezone.now)

    def __str__(self):
        return self.text

此时,每本书都可以有评论。

如何根据书评的平均成绩来处理书。

--补充说明--

    我尝试了一对多,并且可以访问 book.reviews。但是我不能按年级来接近书本

    我尝试了多对多但无法访问 book.reviews

【问题讨论】:

【参考方案1】:

你可以.annotate(..) [Django-doc]这些书:

from django.db.models import Avg

Book.objects.annotate(
    rating=Avg('reviews__grade')
)

thisQuerySet 产生的Book 对象将有一个额外的属性.rating,它是相关grades 的平均值Review 对象。如果没有相关评论,该字段将具有 None 作为值(不要与零 0 混淆)。

【讨论】:

以上是关于Django模型(继承、一对多、多对多)的主要内容,如果未能解决你的问题,请参考以下文章

如何以 django 形式过滤多对多字段

jango 模型管理数据model,数据库外键主键与一对一,一对多,多对多关系

26.Django实现表关系(一对多,一对一,多对多))

26.Django实现表关系(一对多,一对一,多对多))

Django CRM查询(一对多,多对多以及相关的反查)

django模型系统--多对多,一对一以及跨表查询