根据django中的某些条件创建对象 [英] creating an object based on some conditions in 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()
在这里,我通过上下文
。
Here I am passing the showcase
object to Collaborator via context
.
这篇关于根据django中的某些条件创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!