如何从 ForeignKey 的管理器访问自定义 QuerySet 方法
How to access custom QuerySet methods from the Manager of a ForeignKey
我正在使用 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()
managers.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'
我该如何解决这个问题。如何自定义管理器以考虑模型关系。
我认为您的方法不需要 Manager
和 QuerySet
。您可以取消 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 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()
managers.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'
我该如何解决这个问题。如何自定义管理器以考虑模型关系。
我认为您的方法不需要 Manager
和 QuerySet
。您可以取消 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()
我认为您可以使用此设置访问自定义查询集方法。