Это действительно так. И имеет больше смысла, чем то, что я там делал. Мой мозг немного исказился от всего, что я пытался привести в движение до твоей помощи. Большое спасибо!
уверен, как точно выразить это словами, но я пытаюсь использовать собственный QuerySet для модели, но я хочу аннотировать результаты любого набора запросов. Итак, были ли применены фильтры, или это было прямое получение объекта (который, я думаю, все еще является вызовом filter () в конце), я хочу, чтобы аннотации применялись, чтобы я мог получить к ним доступ в объектах Model, которые я получаю обратно. ,
Мое текущее решение использует пользовательский менеджер QuerySet +, и пользовательский менеджер передает пользовательские вызовы соответствующему вызову в пользовательском наборе запросов. Конечно, к сожалению, необходимо сопоставить методы между менеджером и набором запросов для любого пользовательского метода, который я хочу.
я знаю этоCustomQuerySet.as_manager()
существует, чтобы избежать этого дублирования, но если я использую это, то я теряю способность переопределять get_queryset (), поэтому мои аннотации могут применяться во всех случаях оценки набора запросов.
Есть ли более чистый способ сделать это, так что у меня все еще есть возможность цепочки вызовов и мои аннотации применяются, когда набор запросов наконец оценивается?
В идеале я хотел бы продолжать использовать стандартные вызовы, такие как:Model.objects.most_liked().near()
а такжеModel.objects.get(id=model_id)
В отличие от необходимости делать что-то вроде добавления метода add_annotations () в мой пользовательский QuerySet, тем самым необходимо всегда вызывать этот метод каждый раз, когда я получаю объекты Model (т.е. я не хочуModel.objects.g,et(id=id).add_annotations()
а такжеModel.objects.near().add_annotations()
и так далее)
но не нужно ли повторять методы между менеджером и набором запросов? В идеале, без взлома частных методов или чего-то в этом роде. Я кратко поиграл с переопределением__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()