仅在创建新帖子时运行序列化程序的验证

dev*_*mrh 5 django django-rest-framework

我有2种视图-其中一种使用create,另一种使用RetrieveUpdateDestroyAPIView。两者都使用相同的Serializer类。我仅在创建新帖子时才需要标题验证,而在更新帖子时则不需要。
我使用“ PUT”请求更新某些帖子时出现标题验证错误。
我怎样才能解决这个问题?

class StoreApiView(mixins.CreateModelMixin, generics.ListAPIView):
    lookup_field = 'pk'
    serializer_class = ProductSerializer

    def get_queryset(self):
        qs = Product.objects.all()
        query = self.request.GET.get('q')
        if query is not None:
            qs = qs.filter(
                Q(title__icontains=query) |
                Q(description__icontains=query)
            ).distinct()
        return qs

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)


class StoreRucView(generics.RetrieveUpdateDestroyAPIView):
    lookup_field = 'pk'
    serializer_class = ProductSerializer
    permission_classes = [IsOwnerOrReadOnly]


    def get_queryset(self):
        return Product.objects.all()
Run Code Online (Sandbox Code Playgroud)

这是序列化器类的完整代码:

class ProductSerializer(ModelSerializer):
    product_ratings = ProductRatingSerializer(many=True,read_only=True)
    product_badges_set = ProductBadgesSerializer(many=True,read_only=True)

    author = serializers.SerializerMethodField()
    category = serializers.SerializerMethodField()

    def get_author(self, obj):
        return obj.author.first_name+' '+obj.author.last_name

    def get_category(self, obj):
        return obj.category.title

    class Meta:
        model = Product
        fields = [
            'product_id',
            'author',
            'category',
            'title',
            'description',
            'price',
            'level',
            'video_length',
            'created_date',
            'updated_date',
            'product_ratings',
            'product_badges_set',
        ]
        read_only_fields = ['product_id', 'created_date', 'updated_date', 'author']

    def validate_title(self, value):

        qs = Product.objects.filter(title__iexact=value)
        if self.instance:
            qs.exclude(pk=self.instance.pk)
        if qs.exists():
            raise serializers.ValidationError("this title is already used")
        return value
Run Code Online (Sandbox Code Playgroud)

nev*_*ner 5

您可以在序列化程序中传递附加上下文。并检查此上下文的值validate_title。视图中:

def get_serializer_context(self):
    context = super().get_serializer_context()
    context['is_create'] = True 
    return context 

def perform_create(self, serializer):
    serializer.save(author=self.request.user)
Run Code Online (Sandbox Code Playgroud)

在序列化器中:

def validate_title(self, value):
  if self.context.get('is_create'):   
    qs = Product.objects.filter(title__iexact=value)
    if self.instance:
        qs.exclude(pk=self.instance.pk)
    if qs.exists():
        raise serializers.ValidationError("this title is already used")
    return value
Run Code Online (Sandbox Code Playgroud)

  • 在“POST”请求之后创建新帖子,在“PUT”请求之后更新。你的解决方案不是重新发明轮子吗?为什么不检查请求类型呢? (4认同)