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>.

Вернуться на верх