Django-viewsets.Как получить параметр ID из пути в execute_create fun - PullRequest
0 голосов
/ 21 сентября 2019

Я пытаюсь сделать REST в Django, используя библиотеку VIEWSETS.Я создал модель контейнера, которая работает хорошо.Контейнер связан с моделью ContainerModerator.Конечная точка должна быть:

POST-контейнеры / {container_id} / moderators

Одним из полей в ContainerModerator является container_id.Я хотел бы получить это с пути.

Ниже то, что у меня есть сейчас.Я пытался по-разному туда добраться.Я также читаю похожие посты, обычно для библиотеки, отличной от VIEWSETS.Я новичок, и мне интересно, есть ли простое, элегантное решение для этого случая, которое мне будет легко понять?Следует ли мне использовать другие библиотеки, такие как APIVIEW или GenericAPIView?

модели:

class ContainerModerator(models.Model):
  moderator_id = models.ForeignKey(settings.AUTH_USER_MODEL, 
                 on_delete=models.CASCADE)
  container_id = models.ForeignKey(Container, on_delete=models.CASCADE)

сериализаторы:

class ContainerModeratorSerializer(serializers.ModelSerializer):

  class Meta:
    model = models.ContainerModerator
    fields = '__all__'

просмотров:

class ContainerModeratorViewSet(viewsets.ModelViewSet):
  serializer_class = serializers.ContainerModeratorSerializer
  queryset = models.ContainerModerator.objects.all()

  def perform_create(self, serializer):
    serializer.save()

urls:

router.register('v1/containers/<int:container_id>/moderators', 
views.ContainerModeratorViewSet)

urlpatterns = [
  path('', include(router.urls))
]

Ответы [ 2 ]

0 голосов
/ 24 сентября 2019

Вы можете получить container_id из self.kwargs['container_id'] и выполнить поиск экземпляра контейнера с помощью container_id.В частности, вам нужно что-то вроде этого в вашем наборе:

class ContainerModeratorViewSet(viewsets.ModelViewSet):
     serializer_class = serializers.ContainerModeratorSerializer
     queryset = models.ContainerModerator.objects.all()

     def get_object(self):
         #Override this method to get your cantainer instance
         return get_object_or_404(Container, id=self.kwargs['pk']) 

     def post(self, request, *args, **kwargs)):

        instance = self.get_object()
        data = {
           container : instance.id,
           moderator : request.user
        }

        return self.create(data)

    def create(self, data):
       serializer = self.get_serializer(data=data)

       self.permform_create(serializer)
       return Response(serializer.data)

    def perform_create(self, serializer):
        serializer.save()

Просто внимательно прочитайте исходный код GenericAPIView, ModelViewSet и ViewMixins, чтобы увидеть, как они соединяются друг с другом.

0 голосов
/ 22 сентября 2019

Вы можете сделать это просто с помощью метода self.get_object(), который доступен под RetrieveModelMixin

Вот реализация RetrieveModelMixin,

def retrieve(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance)
    return Response(serializer.data)

Класс ModelViewSet наследуется от GenericAPIView и включает в себя реализации для различных действий, смешивая поведение различных классов mixin.

Действиями, предоставляемыми классом ModelViewSet, являются .list (), .retrieve (), .create(), .update (), .partial_update () и .destroy ().

https://www.django -rest-framework.org / api-guide / viewsets / # modelviewset

...