我不确定如何在这个词上精确地写一些字,但是我想做的是为模型使用自定义QuerySet,但是我想注释任何queryset的结果。因此,无论是应用过滤器,还是直接获取对象(我认为最后仍然是filter()调用),我都希望应用注释,以便可以在返回的Model对象中访问它们。
我当前的解决方案是使用自定义QuerySet +自定义管理器,并且自定义管理器将自定义调用传递给自定义Queryset上的相应调用。当然,不幸的是,对于我想要的任何自定义方法,都需要在管理器和查询集之间匹配方法。
我知道CustomQuerySet.as_manager()可以避免这种重复,但是如果使用它,那么我将失去覆盖get_queryset()的能力,因此我的注释可以应用于评估查询集的所有情况。
有没有更清洁的方法可以执行此操作,因此在最终评估查询集时,我仍然可以链接调用并应用我的注释?
理想情况下,我想继续使用标准呼叫,例如:
Model.objects.most_liked().near()
和
Model.objects.get(id=model_id)
而不是让做类似的东西添加add_annotations()方法来我的自定义查询集,从而需要始终调用该方法,每当我想模型对象(即我不想Model.objects.get(id=id).add_annotations()和Model.objects.near().add_annotations()等)
但不必在manager和queryset之间重复这些方法?理想情况下,无需侵入私有方法或类似方法。我曾短暂地__iter__尝试重写CustomQuerySet类以添加注释,但是这样做似乎不合适。
下面是模型,查询集和管理器的样本设置。这些当然不是我的真实班级名字,只是问题的填充物。希望我已经包括了足够多的内容来使我的问题易于理解:)
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()
Run Code Online (Sandbox Code Playgroud)