Как заставить фильтр QuerySet использовать перегруженный оператор сравнения?

У меня есть модель с OneToOneField, указывающая на модель с параметрами. Последнее перегружает операторы сравнения python, такие как <.

models.py:

class SomeComplexParameter(models.Model):
    fid = models.UUIDField(primary_key=True, default=uuid.uuid4)
    value = models.PositiveIntegerField(default=10)

    def __lt__(self, other):
        return self.value < other.value

class SomeModel(models.Model):
    ...
    param = models.OneToOneField(SomeComplexParameter,on_delete=models.CASCADE, null=True)
    ...

Когда я пытаюсь фильтровать SomeModel наборы запросов с помощью цепочки param__lt, перегруженный метод __lt__ не вызывается!

Например:

Если я определяю порог SomeComplexParameter экземпляра

p_threshold = SomeComplexParameter.objects.create(value=30)

и фильтровать SomeModel наборы запросов с помощью

SomeModel.objects.filter(param__lt=p_threshold)

каждый раз возвращает случайный набор SomeModel экземпляров.

Что я пробовал до сих пор:

print(SomeModel.objects.filter(param__lt=p_threshold).query)

дает

SELECT "bricks_somemodel"."fid", "bricks_somemodel"."param_id" FROM "bricks_somemodel" WHERE "bricks_somemodel"."param_id" < 68e1c73401c5412bb91f4cb75ce57e8e

что указывает на то, что Django не использует перегруженный оператор. Вместо этого он сравнивает uuids (pk для этой модели). Это объясняет случайность!

Я проверил, что

SomeModel.objects.filter(param__value__lt=30)

фильтры правильно, так как он использует родной оператор python <. Но для меня это не подходит, так как я должен использовать перегруженный метод __lt__ на SomeComplexParameter.

Есть ли способ настроить мои модели так, чтобы фильтрация с помощью param__lt=p_threshold использовала переопределенный оператор __lt__?

Информация о версии: Django 3.2.13, Python 3.9.0, sqlite

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