无法根据url参数在viewset自定义视图中创建记录

时间:2019-06-26 19:04:49

标签: python django django-rest-framework

你好,我有一个Django rest框架视图集。对于创建视图,我想创建一个自定义视图,该视图将基于通过URL传递的两个不同参数(名称空间和路径)创建一个新记录。我看了看文档,但找不到它的外观。我不确定要根据两个url参数创建记录的必要步骤。

我基本上尝试将create设置为CreateAPIView,但是没有用

class PreferenceViewSet(viewsets.ViewSet):
    queryset = Preference.objects.all()
    serializer_class = PreferenceSerializer

    def get_permissions(self):
        if self.action == 'create' or self.action == 'destroy':
            permission_classes = [IsAuthenticated]
        else: 
            permission_classes = [IsAdminUser]
        return [permission() for permission in permission_classes]

    def list(self, request):
        queryset = Preference.objects.all()
        serializer = PreferenceSerializer(queryset, many=True)
        return Response(serializer.data)

    def create(self, request):
        queryset = Preference.objects.all()
        serializer = PreferenceSerializer(queryset, many=True)
        return Response(serializer.data)

我想将create设置为使用在网址中传递的两个参数来创建首选项

path('preferences/<str:namespace>/<str:path>', preference_path, name='preference-path'),

我希望它使用名称空间和路径创建一个新对象

1 个答案:

答案 0 :(得分:0)

您需要执行以下两个步骤:

  1. 将url参数从视图集添加到序列化程序上下文中
  2. 在序列化程序上覆盖create方法,并使用在上下文中传递的数据来创建记录

因此,首先覆盖get_serializer_context方法将参数添加到上下文:

class PreferenceViewSet(viewsets.ViewSet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._namespace = None
        self._path = None
    ...
    ...

    def get_serializer_context(self):
        context = super().get_serializer_context()
        context.update(namespace=self._namespace, path=self._path)
        return context

    def create(self, request):
        self._namespace = self.kwargs['namespace']
        self._path = self.kwargs['path']

        queryset = Preference.objects.all()
        serializer = PreferenceSerializer(queryset, many=True)
        return Response(serializer.data)

现在,您可以访问序列化程序的重写create方法内的参数,并根据需要创建记录,例如:

class PreferenceSerializer(serializers.HyperlinkedModelSerializer):
    ...
    ...
    def create(self, validated_data):
        namespace = self.context['namespace']
        path = self.context['path']
        # Create object here based on the params