【发布时间】:2017-07-20 01:38:09
【问题描述】:
我不确定如何准确地说明这一点,但我想做的是为模型使用自定义 QuerySet,但我想注释任何查询集的结果。因此,无论是应用了过滤器,还是直接获取对象(我认为最终仍然是 filter() 调用),我都希望应用注释,以便我可以在返回的模型对象中访问它们.
我当前的解决方案是使用自定义 QuerySet + 自定义管理器,自定义管理器将自定义调用传递给自定义查询集上的适当调用。当然,不幸的是,我需要在管理器和查询集之间为我想要的任何自定义方法匹配方法。
我知道 CustomQuerySet.as_manager() 的存在是为了避免这种重复,但如果我使用它,那么我将失去覆盖 get_queryset() 的能力,因此我的注释可以应用于评估查询集的所有情况。
有没有更简洁的方法来做到这一点,所以我仍然可以在最终评估查询集时链接调用并应用我的注释?
理想情况下,我希望继续使用标准调用,例如:
Model.objects.most_liked().near()
和
Model.objects.get(id=model_id)
而不是像添加一个 add_annotations() 方法到我的自定义 QuerySet 那样,因此需要在我得到模型对象的任何时候调用该方法(即,我不想要 Model.objects.get(id=id).add_annotations() 和 Model.objects.near().add_annotations() 和等等)
但不必重复管理器和查询集之间的方法?理想情况下,不要侵入私有方法或类似的东西。我简单地玩弄了在 CustomQuerySet 类上覆盖 __iter__ 以添加注释,但这样做似乎不正确。
模型、查询集和管理器的示例设置如下。这些当然不是我真正的班级名称,只是问题的填充物。希望我已经包含了足够的内容以使我的问题可以理解:)
class CustomQuerySet(models.QuerySet):
def most_liked(self):
return self.filter(...)
def near(self):
return self.filter(...)
class CustomManager(models.Manager):
def get_queryset(self):
return CustomQuerySet(self.model, using=self._db)\
.annotate(...)\
.annotate(...)
def near(self, latitude, longitude, radius, max_results=100):
return self.get_queryset().near()
def most_liked(self):
return self.get_queryset().most_liked()
class Model(models.Model):
objects = CustomManager()
【问题讨论】:
标签: django django-models