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.
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.
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()