использовать django-фильтр с объектом url_params - PullRequest
0 голосов
/ 15 сентября 2018

Я успешно внедрил django-фильтр на моем сервере Django-rest-framework.

У меня есть следующий класс_фильтров

filters.py

class EmploymentFilter(filters.FilterSet):
    class Meta:
        model = EmploymentCheck
        fields  = ['instructions',]

views.py

class EmploymentCheckViewSet(viewsets.ModelViewSet):
    pagination_class = ContentRangeHeaderPagination
    serializer_class = EmploymentCheckSerializer
    queryset = EmploymentCheck.objects.all()
    filter_class = EmploymentFilter

фильтр работает, когда я отправляю запрос на получение как

/ employmentcheck /? Инструкция = 2

Тем не менее, я реализовал интерфейс с response-admin . Мой интерфейс отправляет запрос с url_params в качестве объектов

* +1025 * / employmentcheck / фильтр = { "instruction_id": "2"}? & Диапазон = [0,24] & рода = [ "Идентификатор", "по убыванию"] / * * тысяча двадцать шесть

Обратите внимание, как URL-адрес определяет объект фильтра, в котором он определяет параметры для фильтрации.

Мой вопрос: как и где я могу отфильтровать мою модель, не меняя шаблон URL с моего клиента? Любые другие советы, которые охватывают сферу моего вопроса, также приветствуются

Models.py

class EmploymentCheck(models.Model):
    instructions = models.ForeignKey(Instruction, on_delete=models.CASCADE, null=True)

1 Ответ

0 голосов
/ 17 сентября 2018

Я просто опустил filter_class и вместо этого переопределил метод get_queryset () для viewset.

Позвольте мне внести некоторые изменения, закомментированный код завершится ошибкой, если вы отправите запрос без параметров фильтра. например, GET: / api / employee / в отличие от GET: / api / employee /? filter {"инструкция" = ""}

Поэтому я решил проверить, не равен ли query_params.get ('key'), если да, я передаю пустую строку.

Рекомендуется любой лучший питонский способ обращения с этим

Viewset

class EmploymentCheckViewSet(viewsets.ModelViewSet):
    serializer_class = EmploymentCheckSerializer

    def get_queryset(self):
        queryset = EmploymentCheck.objects.all()

        if self.request.query_params.get('filter') is None:
            return queryset #return the queryset as is
        else:
        _instructions = self.request.query_params.get('filter')            #returned as a string
        _instructions = json.loads(_instructions)#convert to dictionary
        if queryset and any(_instructions):
            queryset = queryset.filter(instructions = _instructions['instruction_id'])
            return queryset

Примечание. При переопределении get_queryset вы должны явно определить аргумент base_name метода router.register в вашем app.urls.py. Обратитесь к маршрутизаторам django-rest-framework .

urls.py

router = DefaultRouter()
router.register(r'employmentcheck', views.EmploymentCheckViewSet, 'EmploymentCheck')#explicitly set the base_name attribute when the viewset defines a custom get_queryset method
...