如何从ForeignKey的管理器访问自定义QuerySet方法



我正在使用Django Manager来制作更高的API来与我的数据库交互,并保持我的代码更干净、更可读。但如果我有Foreignkey关系,我就不能使用ForeignKey模型的管理器。查询更复杂,如下所示,但我只是简化了示例,这样可以更容易地阅读和了解问题的想法:

型号.py:

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

class Inscription(models.Model):
    objects = InscriptionManager()
    ...
    community = models.ForeignKey("Community", related_name="inscriptions")
    created_at = models.DateTimeField()

经理.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'

我该如何解决这个问题。如何定制经理以考虑模型关系

我认为在您的方法中不需要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()

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

最新更新