Модели Django с жестко закодированными полями модели в наборах фильтров

Этот вопрос касается фильтрации. Но чтобы объяснить, вот несколько подтверждающих фактов...

В моей программе есть концепция объектов, которые могут быть виртуальными или не виртуальными. Используя rest_framework, я имею две модели в файле models.py:

class ModelA(models.Model):
    @property
    def is_virtual(self):
        return False

class ModelB(ModelA):
    @property
    def is_virtual(self):
        return True

Итак, ModelB наследует ModelA. И ВСЕ объекты ModelA НЕ виртуальны, а ВСЕ объекты ModelB виртуальны. Вместо того чтобы добавлять это в базу данных, где столбец всегда будет True для ModelA и False для ModelB, я хотел бы жестко закодировать это в классе модели и поддерживающих классах.

В моем файле serializers.py есть:

class ModelSerializer(serializers.ModelSerializer):
    is_virtual = serializers.SerializerMethodField()

    def get_is_virtual(self, obj):
        return obj.is_virtual

class ModelASerializer(ModelSerializer):
    class Meta:
        model = ModelA
        fields = '__all__'

class ModelBSerializer(ModelSerializer):
    class Meta:
        model = ModelB
        fields = '__all__'

Все это в принципе работает, пока я не захочу отфильтровать поиск по is_virtual. В моем filters.py:

class ModelFilterSet(filters.FilterSet):
    is_virtual = filters.BooleanFilter(method='filter_is_virtual')

    def filter_is_virtual(self, queryset, name, value):
        if value:
            return queryset.filter(is_virtual=True)
        else:
            return queryset.filter(is_virtual=False)

Затем, когда я получаю GET http://localhost:8080/api/modela/?is_virtual=false, я получаю:

Я вижу, что он жалуется на строку в filters.py:

else:
    return queryset.filter(is_virtual=False)

Но моя модель объявляет его как свойство, и сериализатор также распознает is_virtual. Что я делаю не так? Заранее спасибо.

Вы можете фильтровать только по полям модели, используя queryset. is_virtual() является методом, а не полем

else: return queryset.filter(is_virtual=False)

Вы можете добавить поле is_virtual следующим образом:

`class ModelA(models.Model):
       is_virtual = models.BooleanField(default=False)`
Вернуться на верх