【问题标题】:How to access custom QuerySet methods from the Manager of a ForeignKey如何从 ForeignKey 的 Manager 访问自定义 QuerySet 方法
【发布时间】:2016-03-23 22:45:12
【问题描述】:

我正在使用 Django Managers 来创建一个更高的 API 来与我的数据库进行交互,并使我的代码更清晰、更易读。但是如果我有Foreignkey 关系,我就不能使用 ForeignKey 模型的管理器。查询更复杂,如下所示,但我只是简化了示例,这样可以更容易阅读和理解问题:

models.py:

class Community(models.Model):
    objects = CommunityManager()
    ...


class Inscription(models.Model):
    objects = InscriptionManager()

    ...
    community = models.ForeignKey("Community", related_name="inscriptions")
    created_at = models.DateTimeField()

ma​​nagers.py:

from datetime import date
from django.db import models


class InscriptionQuerySet(models.query.QuerySet):
    def by_day(self, day=date.today()):
        return self.filter(created_at__day=day)

    ... # more queries


class InscriptionManager(models.Manager):
    def get_query_set(self):
        return InscriptionQuerySet(self.model, using=self._db)

    def today(self):
        return self.get_query_set().by_day()

    ... # more queries


class CommunityQuerySet(models.query.QuerySet):
    def by_type(self, type):
        return self.filter(type=type)

    ... # more queries


class CommunityManager(models.Manager):
    def get_query_set(self):
        return OrganistaionQuerySet(self.model, using=self._db)

    def by_type(self, type):
        return self.get_query_set().by_type(type)

    ... # more queries

用法:

Inscription.objects.by_day() # return correctly all the inscriptions made today
Community.objects.by_type('type1') # return correctly all Communities that match

问题:但问题就在这里

community_b = Community.objects.get(id=12)
community_b.inscriptions.by_day() 
>>> AttributeError: 'ForeignRelatedObjectsDescriptor' object has no attribute 'by_day'

我该如何解决这个问题。如何自定义管理器以考虑模型关系。

【问题讨论】:

  • 您可以尝试将use_for_related_fields = True 添加到您的InscriptionManager 吗?检查这个:docs.djangoproject.com/en/1.9/topics/db/managers/…
  • 为什么两个型号都有QuerySetManager
  • @RohitJain 我试过这个但仍然是同样的错误。是的,它将针对一位经理进行优化,但现在只是为了清楚起见,我对每个模型都使用经理。
  • 仍然不确定为什么你同时拥有 manager 和 QuerySet,但是你能把那个方法移到 QuerySet,并将你模型中的对象分配给 InscriptionQuerySet.as_manager() 吗?我认为这样,它应该工作。它对我有用。
  • 我没明白你在说什么方法。但既然它对你有用。我认为将它作为答案分享会很有帮助。

标签: django django-models django-queryset django-managers


【解决方案1】:

我认为您的方法不需要ManagerQuerySet。你可以取消QuerySet。这就是我通常实现自定义管理器的方式,我尝试在我的一个项目中访问反向关系的自定义管理器方法,它工作正常:

class InscriptionQuerySet(models.QuerySet):
    def by_day(self, day=date.today()):
        return self.filter(created_at__day=day)

    def today(self):
        return self.by_day()

class CommunityQuerySet(models.QuerySet):
    def by_type(self, type):
        return self.filter(type=type)

然后在您的模型中,像这样更改您的objects

class Community(models.Model):
    objects = CommunityQuerySet.as_manager()
    ...


class Inscription(models.Model):
    objects = InscriptionQuerySet.as_manager()

我认为您可以使用此设置访问自定义查询集方法。

【讨论】:

  • 它对我很有用。我使用的方法是在django documentation 中提出的,我不知道这两种方法有什么区别。但是感谢您的提示。
猜你喜欢
  • 2017-06-11
  • 2013-05-12
  • 2021-03-13
  • 1970-01-01
  • 2011-01-10
  • 1970-01-01
  • 2021-05-06
  • 2018-06-15
  • 2013-10-21
相关资源
最近更新 更多