Как использовать lookup_field вместе с FilterSet в Django Rest Framework?

Я работаю над разработкой API для проекта, и он содержит страницу со списком курсов, где

  1. Перечислены все курсы, предлагаемые конкретным колледжем.
  2. Должен поддерживать получение определенного курса с использованием lookup_field как course_slug.
  3. Поддерживает курсы фильтрации на основе некоторых других параметров, которые я реализую с помощью Django FilterSet вместе с filterset_class (filterset_class).

Проблема в том, что после фильтрации курсов на основе требований параметры запроса также включаются в URL-адрес. Теперь я не могу выполнить операцию извлечения на нем, поскольку URL-адрес не может распознать добавленное поле lookup_field и ошибочно принимает его за шаблон в параметрах запроса.

ViewSet.py

class CollegeCourseViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = CourseSerializer
    lookup_field = 'slug'
    filter_backends = (SearchFilter, DjangoFilterBackend,)
    search_fields = ['name']
    filterset_class = CourseFilter

    def get_queryset(self):
        queryset = Course.objects.all()
        return queryset.filter(college_courses__college__slug=self.kwargs['college_slug'])

    def get_object(self):
        obj = super().get_object()
        if self.action == 'retrieve':
            obj.additional = CollegeCourse.objects.filter(course=obj, college__slug=self.kwargs['college_slug']).first()
        return obj

    def get_serializer_class(self):
        if self.action == 'retrieve':
            return CollegeCourseSerializer
        return super().get_serializer_class()

Filters.py

class CourseFilter(filters.FilterSet):
name = filters.MultipleChoiceFilter(field_name='college_courses__stream__name',
                                    choices=choices("STREAM_NAME_CHOICES"))
category = filters.MultipleChoiceFilter(field_name='college_courses__stream__category',
                                        choices=choices("STREAM_CATEGORY_CHOICES"))
program = filters.MultipleChoiceFilter(field_name='college_courses__stream__program',
                                       choices=choices("STREAM_PROGRAM_CHOICES"))

class Meta:
    model = Course
    fields = [
        'name',
        'category',
        'program'
    ]

urls.py

router = routers.DefaultRouter()
router.register(r'courses', CollegeCourseViewSet, basename='college_course')

urlpatterns = [
    path('api/college/v1/colleges/<slug:college_slug>/', include(router.urls)),
]

Предположим, я фильтрую по категории = Сельское хозяйство, я получаю список из трех курсов. Теперь я хотел бы получить один из курсов, используя его слаг. Но вот сообщение о неверном запросе

URL

GET /api/college/v1/colleges/clslug1/courses/?category=Agriculture/crslug2

crslug2 - это слизняк курса.

Сообщение

"Select a valid choice. Agriculture/crslug2 is not one of the available choices."

Есть ли способ добавить lookup_field после параметров запроса?

Заранее спасибо.


person Shreyas Shetty    schedule 20.02.2021    source источник


Ответы (1)


Хорошо, отвечу на мой собственный пост. В основном все было хорошо, за исключением того, что URL-адрес не был RESTful.

Поле lookup_field должно быть указано перед любыми параметрами запроса в API RESTful.

Итак, правильный формат

GET / API / колледж / v1 / колледжи / clslug1 / курсы / crslug2 /? Category = Сельское хозяйство

person Shreyas Shetty    schedule 15.03.2021