python - Django 覆盖查询中双下划线关系查找的行为

标签 python sql django django-models django-orm

我的主要问题:有什么方法可以改变相关查找的行为,例如 MyModel.objects.filter(relationship__field="value")

考虑这个设置。我与自定义管理器建立了一对多关系,该管理器使用 active=False

过滤掉 Books
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 setting Meta.base_manager_name.

警告,不要排除 BaseManager 中的对象仍然有效!

关于python - Django 覆盖查询中双下划线关系查找的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38470569/

相关文章:

mysql - 获得 1 小时的房间可用性增量 MySQL

Python 脚本,运行迭代谷歌搜索并打印热门结果和链接

python - 如何使用 mysql.connector 禁用查询缓存

sql - 连接具有相同层次结构的 2 个 mdx 查询

python - Django 模型 - 如何过滤 ForeignKey 对象的数量

python - 如何在序列化程序创建方法中获取 URL Id?

python - Django模板是否有用于划分的过滤器?

python - celery task_success 与发件人过滤器

python - 使用 Django 在一页上登录和注册表格

mysql - SQL 中的移动平均线