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

Вернуться на верх