Почему мои модели 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
). Хотя в некоторых случаях это полезно, обычно вы вызываете последнюю версию метода и используете предыдущую только для того, чтобы "пропатчить" ее в новой версии этого метода.