在Django Rest Framework中设置slug和用户时创建模型

zbsbpyhn  于 2022-12-24  发布在  Go
关注(0)|答案(3)|浏览(112)

我有一个模型,我用djangorest框架创建了一个示例,序列化器抱怨缺少一个slug和一个空的ForeignKey-Field,它应该指向用户。
我试图在序列化器中重写perform_create来设置这些值,但我意识到在标准CreateModelMixin中:

class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

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

perform_create()之前调用了方法is_valid()。因此,为user填充外键并添加slug不起作用。
有没有合适的方法来解决这个问题,或者我应该重写create

    • 更新日期:**

@Rahul Gupta要求我添加模型和序列化程序。

class ProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = Product
        fields=('id','name','slug',..., 'shop','category')

以及

class Product(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255)
    shop = models.ForeignKey(Shop)
    category = models.ForeignKey("Category")        

    def __unicode__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Product, self).save(*args, **kwargs)

也许我应该说得更清楚一点。在浏览器中,用户填写一个表单来创建一个新的Product示例。但是,用户不需要输入shopslug,因为它们是由自动确定的。Slug来自name,而shop来自另一个模型,该模型链接到request.user

kmbjn2e3

kmbjn2e31#

你不需要从父类中复制粘贴代码,你只需要调用super就可以从父类的create方法中借用功能:

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by('name')
    serializer_class = ProductSerializer

    def create(self, request, *args, **kwargs):
        request.data['shop'] = drequest.user.shop.id
        # Everything above is from Sebastian Langer's answer
        # difference is below: just call parent's `create`:
        return super(ProductViewSet, self).create(request, *args, **kwargs)
7fyelxc5

7fyelxc52#

所以我自己来回答这个问题。我做了一件相当愚蠢的事情--我认为我必须重写序列化器中的create方法,而实际上它似乎是我必须重写的ViewSet中的方法。下面是为我做这件事的代码:

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all().order_by('name')
    serializer_class = ProductSerializer

    def create(self, request, *args, **kwargs):
        request.data['shop']=request.user.shop.id # <-- I ADDED THIS LINE
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

注解“I ADDED THIS LINE”位于我向原始方法添加功能的行中。它完成了这项工作,但可能有一个更优雅的解决方案。可以对slug执行类似的操作。

2eafrhcq

2eafrhcq3#

如果你使用了rest框架和序列化器之后在模型中添加了以下代码:

def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Product, self).save(*args, **kwargs)

您还需要将以下代码添加到模型的序列化器函数中:

slug = serializers.SlugField(required=False)

你就可以走了。

相关问题