Django自定义管理器中如何访问相关模型的状态

3

我在Django中使用model_utils库。

我有两个模型如下所示:

class Book(TimeStampedModel):
    STATUS_CHOICES = Choices(
        (0, 'public', _('public')),
        (1, 'private', _('private')),
    )

    status = models.IntegerField(
        verbose_name=_('status'),
        choices=STATUS_CHOICES,
        default=STATUS_CHOICES.public,
        db_index=True,
    )

class Page(MPTTModel, AbstractPage):
    STATUS_CHOICES = Choices(
        (0, 'draft', _('draft')),
        (1, 'public', _('public')),
        (2, 'private', _('private')),
    )

    status = models.IntegerField(
            verbose_name=_('status'),
            choices=STATUS_CHOICES,
            default=STATUS_CHOICES.public,
            db_index=True,
        )

    book = models.ForeignKey(
            'book.Book',
            verbose_name=_('book'),
            related_name='pages',
            db_index=True,
            on_delete=models.CASCADE,
        )

BookPage模型都有一个名为status的字段。

我在managers.py中有两个自定义查询集类。

class BookQuerySet(models.QuerySet):
    def public(self):
        return self.filter(status=self.model.STATUS_CHOICES.public)

class PageQuerySet(models.QuerySet):    
    def public(self):
        return self.filter(book__status=0,
                           status=self.model.STATUS_CHOICES.public)

如上所示,book__status=0 这段代码确实可以工作,但我有点沮丧,因为我想使用像self.book.model.STATUS_CHOICES.public这样的代码。
请告诉我如何访问相关的模型对象属性。
如果我导入from .models import Book,它会导致"循环导入"。
谢谢。

为什么不使用 book_status=Book.STATUS_CHOICES.public,并在函数中导入 Book 模型。 - Willem Van Onsem
1个回答

2

如果我使用from .models import Book导入,会出现"循环依赖"的问题。

这是正确的,但我们可以绕过它,我们可以将导入延迟到方法中需要时再导入,例如:

# app/managers.py

class BookQuerySet(models.QuerySet):

    def public(self):
        return self.filter(status=self.model.STATUS_CHOICES.public)

class PageQuerySet(models.QuerySet):

    def public(self):
        <b>from .models import Book</b>  # no circular imports
        return self.filter(
            book__status=<b>Book.STATUS_CHOICES.public</b>,
            status=self.model.STATUS_CHOICES.public
        )

谢谢您的快速回复。我之前一直认为所有的导入都必须放在文件顶部。 :-( - pincoin
@nasiajai:当然,如果有很多“东西”需要引用它,最好在顶部导入。但是,在方法中添加导入语句是一种常见的技术,可以“推迟”导入直到调用函数。 - Willem Van Onsem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接