Django - Как зарегистрировать маршрут с параметрами запроса?
Я очень новичок в Django и пытаюсь найти ответ, который ищу. Пожалуйста, потерпите меня.
В моем файле app/urls.py у меня есть
router = routers.DefaultRouter()
router.register(r'drugs', views.DrugViewSet)
В моем файле views.py у меня есть
class DrugViewSet(viewsets.ModelViewSet):
queryset = Drug.objects.all().order_by('name')
serializer_class = DrugSerializer
А мой DrugSerializer
класс выглядит как
class DrugSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Drug
fields = ('id', 'name', 'description', 'recommended_dose_mg', 'count', 'create_date', 'update_date')
Итак, когда я делаю GET на /drugs, я правильно получаю список лекарств. А когда я беру UUID (первичный ключ) конкретного препарата и делаю GET на /drugs/<primary_key>, он правильно извлекает конкретный препарат.
Однако я хочу, чтобы GET на /drugs/<primary_key> отображал другие данные. Я хочу соединить его с другой моделью, которая у меня есть, и вернуть новый json-ответ. Как именно я могу это сделать?
Вы можете использовать Вложенный сериализатор
Например, следующий сериализатор:
class TrackSerializer(serializers.ModelSerializer):
class Meta:
model = Track
fields = ['order', 'title', 'duration']
class AlbumSerializer(serializers.ModelSerializer):
tracks = TrackSerializer(many=True, read_only=True)
class Meta:
model = Album
fields = ['album_name', 'artist', 'tracks']
Сериализуется во вложенное представление следующим образом:
{
'album_name': 'The Grey Album',
'artist': 'Danger Mouse',
'tracks': [
{'order': 1, 'title': 'Public Service Announcement', 'duration': 245},
{'order': 2, 'title': 'What More Can I Say', 'duration': 264},
{'order': 3, 'title': 'Encore', 'duration': 159},
...
],
}
Поле поиска
В ViewSet есть поле под названием lookup_field
. Оно фактически определяет поле модели для использования в такой переменной запроса.
Так вы можете сделать следующее:
class DrugViewSet(viewsets.ModelViewSet):
queryset = Drug.objects.all().order_by('name')
serializer_class = DrugSerializer
lookup_field = 'id'
Вот ссылка на документацию: https://www.django-rest-framework.org/api-guide/generic-views/#attributes
Но на самом деле он генерируется автоматически для действия retrieve в ViewSet и используется id
. Вы можете установить некоторые плагины swagger, чтобы увидеть это.
Например:
Различные сериализаторы
Если вы хотите установить разные сериализаторы для разных действий, вы можете переопределить модель ViewSet под названием get_serializer_class
:
class DrugViewSet(viewsets.ModelViewSet):
queryset = Drug.objects.all().order_by('name')
serializer_class = DrugSerializer
def get_serializer_class(self):
if self.action == 'detail':
return DrugDetailSerializer
return DrugSerializer
Документация здесь: https://www.django-rest-framework.org/api-guide/generic-views/#get_serializer_classself
В DrugDetailSerializer
можно указать, какие данные сериализовать при вызове поля GET /drug/<primary_key>.