Django休息框架: Prevent duplicate objects when using CreateModelMixin

标签 django django-rest-framework

我有一个 View 集,用户可以在其中为特定产品创建评论并列出他们为所有产品创建的所有评论:

class ProductReviewViewset(CreateModelMixin, ListModelMixin, GenericViewSet):
    serializer_class = ProductReviewSerializer

    def get_queryset(self):
        # Return all reviews for user that are not marked as deleted
        user = self.request.user
        return ProductReview.objects.filter(user=user, deleted=False).order_by('review__name')

    def perform_create(self, serializer):
        # Add user to review object before saving
        user = self.request.user
        serializer.save(user=self.request.user)

问题在于,这允许用户为同一对象创建多个评论。我想防止这种情况发生,并且只允许在没有为该产品创建其他评论的情况下创建评论(标记为“已删除”的评论将不被计算在内)。

到目前为止,我能够重写 .create() 方法并在其中进行序列化、验证和检查重复项。

class ProductReviewViewset(CreateModelMixin, ListModelMixin, GenericViewSet):
    serializer_class = ProductReviewSerializer

    def get_queryset(self):
        # Return all reviews for user that are not marked as deleted
        user = self.request.user
        return ProductReview.objects.filter(user=user, deleted=False).order_by('review__name')

    def create(self, request, *args, **kwargs):
        # Override create method to prevent duplicate object creation
        serializer = ProductReviewSerializer(data=self.request.data)
        serializer.is_valid(raise_exception=True)
        user = self.request.user
        product = serializer.validated_data['product']
        exists = ProductReview.objects.filter(user=user, product=product, deleted=False).exists()
        if not exists:
            serializer.save(user=user)
            return Response(status=status.HTTP_201_CREATED)
        else:
            return Response(status=status.HTTP_409_CONFLICT)

有没有更简单或更好的方法来做到这一点?或者这是这样做的方法吗?

谢谢!

最佳答案

另一种方法是使用get_or_create查询集方法:get_or_create

def create(self, request, *args, **kwargs):
    # Override create method to prevent duplicate object creation
    serializer = ProductReviewSerializer(data=self.request.data)
    serializer.is_valid(raise_exception=True)
    user = self.request.user
    product = serializer.validated_data['product']
    obj, created = ProductReview.objects.get_or_create(user=user, product=product, deleted=False, defaults=seriaizer.validated_data)
    if not created:
        serializer.save(user=user)
        return Response(status=status.HTTP_201_CREATED)
    else:
        return Response(status=status.HTTP_409_CONFLICT)
            

并行发出请求时,get_or_create 将防止竞争条件

关于Django休息框架: Prevent duplicate objects when using CreateModelMixin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62380410/

相关文章:

python - Django rest修改用户密码查看

python - Postgres : values query on json key with django

python-3.x - 鹡鸰:Locale_ID 不能为空

python - <myObject> 对象不可迭代,Django REST Framework

mysql - 在 django 中用 group by 列的总和

django - 设置 django-oauth-toolkit 后无法访问管理面板

python - django - 将列表转换回查询集

html - 在 django 中使用 ajax 搜索结果

python - Django 和杰通

python - Django 模型向导 : IntegrityError Column "user_id" cannot be null