#django-rest-framework #django-urls #url-parameters
#django-rest-framework #django-urls #url-параметры
Вопрос:
Я искал ответ в связанных темах, но ни один из них не работал. Итак, следуя указателю Django Rest Guid о фильтрации, я хотел добавить возможность фильтрации данных по URL.
У меня есть свое мнение:
class ArtistList(generics.ListAPIView):
serializer_class = ArtistSerializer
def get_queryset(self):
queryset = Artist.objects.all()
name = self.request.query_params.get('name', None)
print(name)
if name is not None:
queryset = queryset.filter(name=name)
return queryset
и мой файл urls:
urlpatterns = [
...
path('artists/<str:name>', ArtistList.as_view(), name='artists'),
]
Когда я предоставляю url, например: http://localhost:8000/artists?name=A5
, он показывает, что этот URL не существует.
Я также пытался http://localhost:8000/artists/A5
вернуть всех исполнителей вместо только 1.
Я также пытался re_path('^artists/(?P<name>. )/$', ArtistList.as_view(), name='artists'),
, как в примере в руководстве, но все равно получал сообщение об ошибке. Что здесь не так?
У меня также есть второй вопрос. Каков наилучший способ манипулировать URL-адресами с помощью параметров? Я имею в виду, должен ли я объявить первый URL для возврата всего объекта, а второй — только для определенного?
Ответ №1:
Вы путаете две вещи:
- у вас есть путь, который часто является частью хоста, и перед строкой запроса строка запроса начинается с
?
, поэтому путь дляhttp://localhost:8000/artists?name=A5
artists
. Параметры URL помещаются вself.kwargs
; и - у вас есть строка запроса, строка запроса — это коллекция пар ключ-значение, которая начинается после вопросительного знака, в котором хранятся эти элементы
request.query_params
.
Если вы, таким образом, хотите фильтровать с /artists/A5
помощью, тогда вы работаете с:
# http://localhost:8000/artists/A5
class ArtistList(generics.ListAPIView):
serializer_class = ArtistSerializer
def get_queryset(self):
return Artist.objects.filter(name=self.kwargs['name'])
В этом случае вам всегда нужно указывать имя, поскольку, как вы выяснили, его непредоставление вернет ответ HTTP 404.
Если вы хотите использовать строку запроса, вы меняете путь на:
# http://localhost:8000/artists?name=A5
urlpatterns = [
# …,
path('artists/', ArtistList.as_view(), name='artists'),
]
и затем вы используете self.query_params
, как уже делали. В этом случае name=…
часть не требуется.
Комментарии:
1. Спасибо, вы снова помогаете… Это работает, но вместо localhost:8000/artists?name=A5 я получаю localhost:8000/artists/?name=A5 и удаление косой черты не работает
2. @Frendom: это может быть
APPEND_SLASH
настройкой ( docs.djangoproject.com/en/3.1/ref/settings/#append-slash ), или браузер, поскольку обычно они должны быть эквивалентны.3. Я не хочу создавать аналогичный вопрос, но что, если мы захотим добавить еще один параметр (amp;) и использовать его для сортировки моих данных?
4. @Frendom: затем вы снова принимаете этот параметр
self.query_params.get('otherparam')
. Он автоматически декодирует?...=...amp;...=...amp;....=...
объект, подобный словарю.
Ответ №2:
Если вы хотите использовать ссылку http://localhost:8000/artists?name=A5
, просто переименуйте свой путь :
urlpatterns = [
...
path('artists', ArtistList.as_view(), name='artists'),
]
Если вы хотите использовать http://localhost:8000/artists/A5
, используйте не query_params, а kwargs :
name = self.kwargs.get('name', None)
В обоих случаях, если вы хотите вернуть один объект, вы можете захотеть перейти к подробному просмотру. (Использование kwargs обычно связано с представлением сведений)