我不确定如何准确地说出这些内容,但我想要做的是为模型使用自定义QuerySet,但我想注释任何查询集的结果。因此,无论是应用过滤器,还是直接获取对象(我认为最终仍然是一个filter()调用),我希望应用注释,以便我可以在Model对象中访问它们。
我当前的解决方案是使用自定义QuerySet +自定义管理器,自定义管理器将自定义调用传递给自定义Queryset上的相应调用。当然,对于我想要的任何自定义方法,我很遗憾需要在manager和queryset之间匹配方法。
我知道存在CustomQuerySet.as_manager()
以避免这种重复,但是如果我使用它,那么我将失去覆盖get_queryset()的能力,因此我的注释可以应用于评估查询集的所有情况。
有没有更简洁的方法来做到这一点所以我仍然能够链接调用并在最终评估查询集时应用我的注释?
理想情况下,我想继续使用标准调用,例如:
Model.objects.most_liked().near()
和
Model.objects.get(id=model_id)
与必须执行类似添加add_annotations()方法到我的自定义QuerySet的操作相反,因此需要在我获得Model对象时始终调用该方法(即,我不想Model.objects.get(id=id).add_annotations()
和{{ 1}}等等)
但不必重复管理器和查询集之间的方法?理想情况下,不要破解私人方法或类似的东西。我简单地在CustomQuerySet类上重写了Model.objects.near().add_annotations()
以添加注释,但是这样做似乎并不正确。
下面的模型,查询集和管理器的示例设置。这些当然不是我真正的班级名称,只是问题的填充者。希望我已经包含足够的内容以使我的问题可以理解:)
__iter__
答案 0 :(得分:4)
您应该使用from_queryset
方法 - 它允许您创建一个Manager类,您可以在应用于模型之前进一步自定义该类。例如:
class CustomQuerySet(models.QuerySet):
def most_liked(self):
return self.filter(...)
class CustomManager(models.Manager.from_queryset(CustomQuerySet)):
def get_queryset(self):
return super(CustomManager, self).get_queryset() \
.annotate(...)
class Model(models.Model):
objects = CustomManager()