Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 使用2个外键向序列化程序添加字段_Django_Django Models_Django Rest Framework - Fatal编程技术网

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
,它修复了错误。非常感谢你的帮助