仅在创建新帖子时运行Serializer的验证

时间:2018-02-12 09:24:00

标签: 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()

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

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

1 个答案:

答案 0 :(得分:2)

您可以在序列化程序中传递additional context。并在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)

在序列化器中:

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