Django 使用2个外键向序列化程序添加字段
我有两个模型,看起来像这样:Django 使用2个外键向序列化程序添加字段,django,django-models,django-rest-framework,Django,Django Models,Django Rest Framework,我有两个模型,看起来像这样: class Topic(models.Model): name = models.CharField(max_length=25, unique=True) def save(self, *args, **kwargs): topic = Topic.objects.filter(name=self.name) if topic: return topic[0].id su
class Topic(models.Model):
name = models.CharField(max_length=25, unique=True)
def save(self, *args, **kwargs):
topic = Topic.objects.filter(name=self.name)
if topic:
return topic[0].id
super(Topic, self).save(*args, **kwargs)
return self.id
class PostTopic(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
post= models.ForeignKey(Post, on_delete=models.CASCADE)
class Post(models.Model):
# rest of the fields
topics = models.ManyToManyField('Topic', through='PostTopic')
class Topic(models.Model):
name = models.CharField(max_length=25, unique=True)
# def save(self, *args, **kwargs):
# **Important:** Django model's save function does not return anything. So handling it here won't be good. Let us handle duplicate entry in serializer
# topic = Topic.objects.filter(name=self.name)
# if topic:
# return topic[0].id
# super(Topic, self).save(*args, **kwargs)
# return self.id
class PostTopic(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
post= models.ForeignKey(Post, on_delete=models.CASCADE)
如果主题已经在topic
表中,那么我们将返回该主题的id。我们不创造另一个。当用户提交带有标记主题的Post
时(将其视为hashtags),如果Topic
表中不存在这些主题,则这些主题将与PostTopic
中的关系一起创建
话虽如此,我的序列化程序如下所示:
class PostSerializer(serializers.ModelSerializer):
topics = serializers.ListField(
child=serializers.CharField(max_length=256), max_length=3
)
class Meta:
model = Post
fields = ('user', 'status', 'topics')
def create(self, validated_data):
topics= validated_data.pop('topics')
post = Post.objects.create(**validated_data)
for topic in topics:
topic_id = Topic(name=topic).save()
PostTopic(post_id=post.id, topic_id=topic_id).save()
return post
目前,我的序列化程序给了我一个
AttributeError
,因为主题不是Post
中的字段。我怎样才能解决这个问题,让它正常工作?如果我使用PostTopic
,那么我将如何让用户给出实际的主题?我认为您正在寻找Post
和Topic
之间的关系。您可以这样添加它:
class Topic(models.Model):
name = models.CharField(max_length=25, unique=True)
def save(self, *args, **kwargs):
topic = Topic.objects.filter(name=self.name)
if topic:
return topic[0].id
super(Topic, self).save(*args, **kwargs)
return self.id
class PostTopic(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
post= models.ForeignKey(Post, on_delete=models.CASCADE)
class Post(models.Model):
# rest of the fields
topics = models.ManyToManyField('Topic', through='PostTopic')
class Topic(models.Model):
name = models.CharField(max_length=25, unique=True)
# def save(self, *args, **kwargs):
# **Important:** Django model's save function does not return anything. So handling it here won't be good. Let us handle duplicate entry in serializer
# topic = Topic.objects.filter(name=self.name)
# if topic:
# return topic[0].id
# super(Topic, self).save(*args, **kwargs)
# return self.id
class PostTopic(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
post= models.ForeignKey(Post, on_delete=models.CASCADE)
此外,您处理重复项的方法将无法工作,因为模型的save方法不会返回任何内容。让我们在序列化程序中处理它,并进行一些小的修复:
class PostSerializer(serializers.ModelSerializer):
topics = serializers.ListField(
child=serializers.CharField(max_length=256), max_length=3
)
class Meta:
model = Post
fields = ('user', 'status', 'topics')
def create(self, validated_data):
topics= validated_data.pop('topics')
post = Post.objects.create(**validated_data)
for topic in topics:
new_topic, _ = Topic.objects.get_or_create(name=topic)
PostTopic(post_id=post.id, topic=new_topic).save()
return post
嗯,我喜欢你的解决方案,但是我得到了一个错误:
'ManyRelatedManager'对象不可编辑
你能分享你的观点吗?当然这是我对这个序列化程序的唯一观点:类CreateQuestionView(CreateAPIView):序列化程序\u class=CreateQuestionSerializer
我实际上已经修复了它,ListField
应该添加这个write\u only=True
,它修复了错误。非常感谢你的帮助