Ошибка Django-фильтра: 'Meta.fields' не должен содержать немодельные имена полей
Я работаю с Django REST framework и django-filters и хотел бы использовать обратное отношение annotation_set в качестве одного из фильтров для GET API, который использует модель Detection.
Модели следующие:
class Detection(models.Model):
image = models.ImageField(upload_to="detections/images")
def local_image_path(self):
return os.path.join('images' f"{self.id}.jpg")
class Annotation(models.Model):
detection = models.ForeignKey(Detection, on_delete=models.CASCADE)
attribute = models.CharField(max_length=255)
Сериализатор:
class DetectionSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
local_image_path = serializers.CharField()
class Meta:
model = Detection
fields = '__all__'
А набор представлений:
class DetectionTrainingViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet
):
queryset = Detection.objects.all()
serializer_class = DetectionSerializer
filterset_fields = ('annotation_set__id', )
@action(methods=['GET'], detail=False)
def list_ids(self, request):
queryset = self.get_queryset()
filtered_queryset = self.filter_queryset(queryset)
return Response(filtered_queryset.values_list('id', flat=True))
Когда я делаю вызов конечной точки, я получаю ошибку:
'Meta.fields' must not contain non-model field names: annotation_set__id
Разве поле не должно существовать?
Примечание: Я попытался добавить другие поля в модель Annotation, а затем использовать annotation_set__newfield, но у меня по-прежнему возникает ошибка. Я могу подтвердить, что поле newfield существует, поскольку оно правильно сериализуется и возвращается API, когда я закомментирую строку, задающую поле filterset_fields.
Просматривая документацию по фильтрам django, вы могли пропустить ссылку на DjangoFilterBackend, например
queryset = Detection.objects.all()
serializer_class = DetectionSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ('annotation_set__id', )
(см.: https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html)
Очевидно, я должен был явно указать имя обратного отношения:
class Annotation(models.Model):
detection = models.ForeignKey(Detection, on_delete=models.CASCADE, related_name='annotation_set')
attribute = models.CharField(max_length=255)
Если кто-то знает почему, я буду рад узнать это! Спасибо!
Попробуйте это, у меня была похожая проблема, она сработала для меня. В файле представления измените filterset_fields на следующие.
class DetectionTrainingViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet
):
queryset = Detection.objects.all()
serializer_class = DetectionSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = ('annotation__id', )