Почему мои модели Django.Менеджер возвращает все объекты, связанные отношениями?
Я не совсем понимаю, что здесь происходит, но, похоже, super().get_queryset() делает не то, что я думаю?
У меня отношение 1:N, и обратный поиск по умолчанию работает:
>>> for thing in this.thing_set.all():
... print(thing.this)
Каждый из них является This.
Однако, с моими настройками:
>>> for thing in this.thing_set.by_date():
... print(thing.this)
Будет произведено This и `Что*
class ThingByDateManager(models.Manager):
def by_date(self):
return super().get_queryset().order_by("start_time")
Это все, что здесь есть.
class This(models.Model):
name = models.CharField(max_length=255, primary_key=True)
class Thing(models.Model):
start_time = models.DateTimeFiled()
name = models.CharField(max_length=255)
this = models.ForeignKey(This, on_delete=models.CASCADE)
objects = ThingByDateManager()
(возможно, эти модели написаны не совсем идеально, но я надеюсь, что это просто какая-то глупость с набором запросов или что-то в этом роде)
Почему это неправильно фильтрует мои объекты по this, вместо этого возвращая все из Thing?
Я не знаю, правильно ли это делается, но:
return super().all().order_by("start_time")
Кажется, это работает, но я не уверен, в чем разница
Я уже сталкивался с подобной проблемой раньше.
Здесь all() заботится о фильтре, но пользовательский фильтр этого не делает.
Таким образом, другим решением вашей проблемы может быть применение self вместо super().
return super().get_queryset().order_by("start_time")
#change above to below:
return self.get_queryset().order_by("start_time")
Вы не переопределяете get_queryset(), поэтому super().get_queryset() не будет искать QuerySet первого элемента в списке. порядок разрешения метода, но ниже.
Это важно, поскольку такой связанный менеджер подклассифицирует существующий. Действительно, как видно из исходного кода , он переопределяет метод get_queryset() для автоматической фильтрации.
Таким образом, вы должны вызвать self.get_queryset():
class ThingByDateManager(models.Manager):
def by_date(self):
return self.get_queryset().order_by("start_time")
как правило, странно вызывать super().bar() в методе, в котором вы определяете foo (а не bar). Хотя в некоторых случаях это полезно, обычно вы вызываете последнюю версию метода и используете предыдущую только для того, чтобы "пропатчить" ее в новой версии этого метода.