Получение аргументов URL в сериализаторах Django REST Framework
Небольшая заметка о том, как в ClassBasedView Django REST Framework получить значение параметра из URL.
Допустим, наши URL сконфигурированы таким образом:
urls.pyfrom django.conf.urls import url
from .api import ArticleListCreateView
from .api import ArticleDetailView
from .api import ArticleCommentListCreateView
urlpatterns = [
url(r'^article/$', ArticleListCreateView.as_view()),
url(r'^article/((\d+))/$', ArticleDetailView.as_view()),
url(r'^article/((\d+))/comment/$', ArticleCommentListCreateView.as_view()),
]
Делать какую-либо работу для вида ArticleDetailView
не приходится - достаточно создать класс, унаследованный от RetrieveUpdateDestroyAPIView
.
Получить доступ к параметру pk
в виде не проблема, достаточно переопределить метод get_queryset()
, например, так:
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from article.models import Article
from .models import ArticleComment
class ArticleCommentListCreateView(RetrieveUpdateDestroyAPIView):
model = ArticleComment
# Возвращаем только комментарии к указанной статье
def get_queryset(self):
return ArticleComment.objects.filter(article=self.kwargs['pk])
def get_serializer_class(self):
if self.request.method == 'GET':
return ArticleCommentReadSerializer
return ArticleCommentWriteSerializer
А вот получить в сериализаторе значение параметра pk
можно не вполне очевидным способом:
from django.shortcuts import get_object_or_404
from rest_framework import serializers
from .models import ArticleComment
from article.models import Article
# ArticleReadSerializer не описан из-за своей простоты
class ArticleCommentWriteSerializer(serializers.ModelSerializer):
article = serializers.PrimaryKeyRelatedField(
queryset=Article.objects.all(),
default=None
)
# Заменяем валидатор поля article таким образом, чтобы всегда
# подставлялось значение из URL
def validate_article(self, value):
# Кто бы мог подумать???
article_id = self.context['view'].kwargs['pk']
return get_object_or_404(Article, pk=article_id)
class Meta:
model = ArticleComment
Подписаться на:
Комментарии к сообщению
(
Atom
)
Максим, спасибо вам огромное!!!!!!! Как вы додумались до view? Ведь в self ее не видно?
ОтветитьУдалитьберу свои слова обратно - видно) но перекинуть мостик дальше - это очень сильно, ещё раз спасибо
ОтветитьУдалить