0

I have 3 models: Post, Topic, PostTopic. PostTopic contains all the topics related to the Post. The models look like this:

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)

The Topic model cannot have 2 topics that are the same. Here's how my serializer looks like:

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

However, I get an error saying:

Got AttributeError when attempting to get a value for field topics on serializer PostSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Post instance.

I understand what I'm doing wrong, but I'm not sure how I can fix it where I can save the topic in PostTopic too. Is there a better way to do this?

user2896120
  • 3,180
  • 4
  • 40
  • 100
  • Looks like a job for a _nested serializer_. – Ivan Starostin Mar 22 '20 at 19:57
  • @IvanStarostin Why a nested when a ListSerializer can do the same? – user2896120 Mar 22 '20 at 20:04
  • 1
    You've implemented the nested serializer in your own way which ended up with fighting against DRF. There is a more natural and sound to DRF way. – Ivan Starostin Mar 22 '20 at 20:10
  • @IvanStarostin Which model would be the serializer? – user2896120 Mar 22 '20 at 20:20
  • See answer here: [Writable nested serializer with existing objects using Django Rest Framework 3.2.2](https://stackoverflow.com/questions/32123148/writable-nested-serializer-with-existing-objects-using-django-rest-framework-3-2) `owners` is the M2M field same as your topics. – Ivan Starostin Mar 22 '20 at 20:23
  • @IvanStarostin hmm, in this person's question, Listing is the main serializer, where as mine is Post. They have a direct link with `category` whereas `Post` does not have a direct link with `Topic` – user2896120 Mar 22 '20 at 20:35
  • `class PostSerializer: topics = PostTopicSerializer(many=True)` – Ivan Starostin Mar 22 '20 at 20:38
  • @IvanStarostin PostTopic needs a foreign key id of the Topic though...if a person is trying to submit content, he wouldn't use the foreign key...we'd have to take his topics/tags and put them into Topic right? – user2896120 Mar 22 '20 at 20:48
  • Please take a deeper look at the given link. It contains concrete solution for given situation. – Ivan Starostin Mar 22 '20 at 21:10

0 Answers0