我的主要问题:有什么方法可以改变相关查找的行为,例如 MyModel.objects.filter(relationship__field="value")
?
考虑这个设置。我与自定义管理器建立了一对多关系,该管理器使用 active=False
from django.db import models
class ActiveOnly(models.Manager):
use_for_related_fields = True
def get_queryset(self):
return super(ActiveOnly, self).get_queryset().filter(active=True)
class Author(models.Model):
name = models.TextField()
class Book(models.Model):
active = models.BooleanField()
author = models.ForeignKey(Author, related_name="books")
title = models.TextField()
objects = ActiveOnly()
让我们创建一些数据:
jim = Author.objects.create(name="Jim")
ulysses = Book.objects.create(title="Ulysses", author=jim, active=True)
finnegans = Book.objects.create(title="Finnegan's Wake", author=jim, active=False)
bill = Author.objects.create(name="Bill")
hamlet = Book.objects.create(title="Hamlet", author=bill, active=False)
从本质上讲,我永远不想处理不活跃的图书。下面是一些用于测试各种场景的查询。
>>> Book.objects.all().count() # expecting the 1 active book: good
1
>>> jim.books.all() # also expecting only 1: good
1
>>> Author.objects.filter(books__title="Hamlet").first().name
u'Bill'
# ^ this is what I don't want to see, because bill's only book has active=False.
# I want the queryset to return no results.
是否有任何方法来更改books__*
查找的行为,以在active
上包含额外的过滤器?
最佳答案
在Django 1.10 Manager.use_for_related_fields
已弃用,取而代之的是在模型上设置 Meta.base_manager_name
。有关详细信息,请参阅更新的文档:
Model._base_manager
Using managers for related object access
By default, Django uses an instance of the
Model._base_manager
manager class when accessing related objects (i.e.choice.poll
), not the_default_manager
on the related object. This is because Django needs to be able to retrieve the related object, even if it would otherwise be filtered out (and hence be inaccessible) by the default manager.If the normal base manager class (
django.db.models.Manager
) isn’t appropriate for your circumstances, you can tell Django which class to use by settingMeta.base_manager_name
.
警告,不要排除 BaseManager 中的对象仍然有效!
关于python - Django 覆盖查询中双下划线关系查找的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38470569/