Home > other >  Serializers not working on multiple levels as expected in Django
Serializers not working on multiple levels as expected in Django

Time:11-25

I have 4 models and 3 serializers. 1 model is a simple through table containing information about which user posted which reaction about which article.

models.py

class User(AbstractUser):
    id = models.CharField(max_length=36, default=generate_unique_id, primary_key=True)
    username = models.CharField(max_length=250, unique=True) 
...

class Article(models.Model):
    id = models.CharField(max_length=36, default=generate_unique_id, primary_key=True)
    title = models.CharField(max_length=50)
    author = models.ForeignKey(User, related_name='authored', on_delete=models.PROTECT)
...

class Reaction(models.Model):
    user_id = models.ForeignKey(User, related_name='reacted', on_delete=models.CASCADE)
    article_id = models.ForeignKey(Article, related_name='article_details', on_delete=models.CASCADE)
    sentiment = models.ForeignKey(Sentiment, related_name='sentiment', on_delete=models.CASCADE)

class Sentiment(models.Model):
    like = models.IntegerField(default=1)
    dislike = models.IntegerField(default=-1)

serializers.py

class UserSerializer(serializers.ModelSerializer):
    authored = ArticleDetailSerializer(many=True, read_only=True)
    reacted = ReactedSerializer(many=True, read_only=True)
    class Meta:
        fields = (
            'id',
            'username',   
            'authored',
            'reacted',
        )
        model = User

class ArticleDetailSerializer(serializers.ModelSerializer):
    class Meta:
        fields = (
            'id',
            'title',
        )
        model = Article
        
class ReactedSerializer(serializers.ModelSerializer):
    article_details = ArticleDetailSerializer(many=True, read_only=True)
    class Meta:
        fields = (
            'sentiment',
            'article_id',
            'article_details',
        )
        model = Reaction

Currently, the output for a GET request for a User shows authored correctly. authored array results I copied the logic so reacted can be a multi-level object containing sentiment and the relevant article information.

I've tried many solutions yet the result for the User field reacted never includes the article_details field. reacted array results I've ensured the related_name field in in the Reacted model is article_details so what am I missing?

I've seen another solution on StackOverflow where someone had multi-level serialization so why is it not working here?

CodePudding user response:

related_name is useful when you are trying to access reverse relations. For example if you need to acces Reaction from Article object. But in your case you just want to access article details defined inside Reaction model. So you need to use acticle_id field name instead of article_details:

class ReactedSerializer(serializers.ModelSerializer):
    article_id = ArticleDetailSerializer(read_only=True)
    class Meta:
        fields = (
            'sentiment',
            'article_id',
        )
        model = Reaction

UPD: actually article_details is not appropriate naming for related_name here. Since related name is used when you acces list of related objects from other model, in your case it's Article. So it's better ot rename it to reactions:

article_id = models.ForeignKey(Article, related_name='reactions', on_delete=models.CASCADE)

And you can use it like this:

article_obj.reactions.all()
  • Related