Как обработать path-параметры?

Рейтинг: 1Ответов: 1Опубликовано: 14.03.2023

Пишу API на Django REST framework.
Допустим, есть такой url: api/category//?product=product&param1=param1/

Здесь id - это идентификатор записи в модели Product.
product, param2 и т.п. - это path-параметры, которые могут быть переданы, а могут и не быть.
По факту product = ForeignKey('Category').
param1 - тут разные параметры, в частности, это может быть поле модели Product.

Вьюха возвращает queryset из Category. Если объект не найден, то должна быть ошибка 404.
Если id категории передан неверно (неверный формат, несуществующий id), то тоже возвращаем 404. Если id передан верно, но у него неправильно указан или отсутствует product, то тоже 404.

Сейчас в случае таких ошибок возвращается ошибка 500.

Собственно вопрос. Как обрабатывать входящие параметры?

Я могу их вытащить из url например, так:

id_param = self.kwargs.get('id')
param1 = params1.get('param1', None)

Далее делаю примерно так:

try:
   queryset = queryset = Category.objects.get(id=id_param)
except:
   content = {'Объект не найден': 'Значение {} имеет неверный формат'.format(id_param)}
   return Response(content, status=status.HTTP_404_NOT_FOUND)

И единственная мысль - проверять каждый параметр последовательно. То есть сначала получаю категорию. Если ее нет, то выбрасываю исключение 404. Если она есть, то для нее проверяю продукт. Если его нет, то выбрасываю исключение 404. И так далее, последовательно по всем параметрам, пока не сформирую искомый queryset.

Но правильно ли я делаю? Уверен, есть куда более элегантное решение. Подскажите, пожалуйста.

Ответы

▲ 1Принят

Мне кажется, что вы пытаетесь создать функционал, который уже существует. Конкретно для drf вы можете найти фильтрацию по паратетрам здесь.

И в документации по django вы можете найти метод get-object-or-404, который дает возможность избегать написание исключений типа DoesNotExist.

Данный метод может принимать входным аргументом QuerySet основанным на фильтре или цепочке фильтров, если параметров в строке больше одного.

UPD

По просьбе из комментария добавлю вывод для exception (взято из документации)

try:
   queryset = queryset = Category.objects.get(id=id_param)
except Exception as inst:
   content = {'status': 'exception', 'message': inst}
...
""" пример-пояснение из документации
except Exception as inst:
    print(type(inst))    # the exception instance
    print(inst.args)     # arguments stored in .args
    print(inst)          # __str__ allows args to be printed directly,
                         # but may be overridden in exception subclasses
"""