Модели 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)`