根据django中的某些条件创建对象 [英] creating an object based on some conditions in django

查看:73
本文介绍了根据django中的某些条件创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 Showcase 的模型,供用户用来展示项目。我正在尝试实现一种情况,展示柜中的 Administrators 字段中的任何管理员都可以通过 Collaborator 模型添加协作者。当我在下面运行代码时,我会在/ api / showcase / the-gods-must-be-crazy-zz2fox / collaborator上获得

I have a model called Showcase that users use to showcase projects. I am trying to implement a case where any administrator in the Administrators field in the showcase can add collaborators through the Collaborator model. When I run my code below, I get

IntegrityError / create /
NOT NULL约束失败:Shower_collaborator.user_id

models.py

models.py

class Showcase(models.Model):
    title = models.CharField(max_length=50)
    description = models.TextField(null=True)
    skill_type = models.ForeignKey(Skill, on_delete=models.CASCADE)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING, related_name="Showcases")
    content = models.TextField(null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    voters = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="upvotes")
    slug = models.SlugField(max_length=255, unique=True)
    administrator = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="administrators", blank=True)


class Collaborator(models.Model):
    post = models.ForeignKey(Showcase, on_delete=models.CASCADE, related_name="collaborated_showcases")
    user = models.ForeignKey(settings.AUTH_USER_MODEL, 
                            on_delete=models.CASCADE, related_name="collaborators")
    skill = models.ForeignKey(Skill, on_delete=models.CASCADE, null=True, related_name="creative_type")
    role = models.TextField(null=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)

序列化器

class CollaboratorSerializer(serializers.ModelSerializer):
    post = serializers.SlugRelatedField(read_only=True, slug_field='slug')

    class Meta:
        model = Collaborator
        exclude = ['created_on', 'updated_on']

class ShowcaseAdminSerializer(serializers.ModelSerializer):
    administrator = serializers.SlugRelatedField(slug_field='slug', many=True, queryset=User.objects.all())

    class Meta:
        model = Showcase
        fields = ['administrator',]

    def update(self, instance, validated_data):
        users = validated_data.get('administrator')
        for user in users:
            instance.administrator.add(user)
        return instance

views.py

class collaboratorCreateView(APIView):
    '''
    add collaborator to a showcase
    '''
    serializer_class = CollaboratorSerializer
    permission_classes = [IsAdmin]

    def post(self, request, slug):
        showcase = get_object_or_404(Showcase, slug=slug)

        try:
            self.check_object_permissions(request, showcase)
            collaborator = Collaborator.objects.create(
                post = showcase
            )
            serializer = self.serializer_class(collaborator, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except APIException:
            return Response(status=status.HTTP_403_FORBIDDEN)

URL

path("<slug:slug>/collaborator/create/", qv.collaboratorCreateView.as_view(), name="add-collaborator-to-showcase"),

另外,我想知道如果可能的话,如何防止创建重复的用户作为协作者。我猜想if语句可以解决问题,但是我不知道该怎么做,因为我不知道如何获取用户输入以检查视图。

also, as an extra, I was wondering how to prevent creating a duplicate user as a collaborator if possible. I am guessing an if statement MIGHT solve the problem, but I am lost about that because I don't know how to get user input to check in the view.

推荐答案

正如错误所述,您需要在此处为​​模型中的 user 属性提供值。因此,您可以这样操作。

As the error said, you need to provide value for user attribute in model here. So you can do it like this.

首先,更新序列化程序:

First, update the serializer:

class CollaboratorSerializer(serializers.ModelSerializer):
    post = serializers.SlugRelatedField(read_only=True, slug_field='slug')

    class Meta:
        model = Collaborator
        exclude = ['created_on', 'updated_on', 'user']

    def validate_user(self, value):
        showcase = self.context.get('post')
        if showcase.collaborated_showcases.filter(user=value).exists():
            raise serializers.ValidationError("Can't add an existing collaborator to a showcase")
        return value

   def create(self, validated_data):
       validated_data['post'] = self.context['post']
       return super(CollaboratorSerializer, self).create(validated_data)

然后更新视图:

class collaboratorCreateView(APIView):
    '''
    add collaborator to a showcase
    '''
    serializer_class = CollaboratorSerializer
    permission_classes = [IsAdmin]

    def post(self, request, slug):
        showcase = get_object_or_404(Showcase, slug=slug)

        try:
            self.check_object_permissions(request, showcase)
            serializer = self.serializer_class(data=request.data, context={'post':showcase})
            if serializer.is_valid():
                serializer.save()

在这里,我通过展示柜对象传递给协作者guide / serializers /#includes-extra-context rel = nofollow noreferrer> 上下文

Here I am passing the showcase object to Collaborator via context.

这篇关于根据django中的某些条件创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆