Сериализаторы не работают на нескольких уровнях, как ожидалось в Django
У меня есть 4 модели и 3 сериализатора. 1 модель - это простая сквозная таблица, содержащая информацию о том, какой пользователь разместил какую реакцию на какую статью.
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
В настоящее время вывод для GET-запроса для пользователя показывает authored правильно.
Я скопировал логику, чтобы reacted мог быть многоуровневым объектом, содержащим sentiment и соответствующую информацию о статье.
Я пробовал много решений, но результат для поля User reacted никогда не включает поле article_details.
Я убедился, что поле related_name в модели Reacted имеет значение article_details, так что же я упускаю?
Я видел другое решение на StackOverflow, где кто-то использовал многоуровневую сериализацию, так почему же она не работает здесь?
related_name полезно, когда вы пытаетесь получить доступ к обратным отношениям. Например, если вам нужно получить доступ к Reaction из объекта Article. Но в вашем случае вы просто хотите получить доступ к деталям статьи, определенным в модели Reaction. Поэтому вам нужно использовать имя поля acticle_id вместо article_details:
class ReactedSerializer(serializers.ModelSerializer):
article_id = ArticleDetailSerializer(read_only=True)
class Meta:
fields = (
'sentiment',
'article_id',
)
model = Reaction
UPD: на самом деле article_details не является подходящим именованием для related_name здесь. Поскольку связанное имя используется, когда вы получаете список связанных объектов из другой модели, в вашем случае это Article. Поэтому лучше переименовать его в reactions:
article_id = models.ForeignKey(Article, related_name='reactions', on_delete=models.CASCADE)
И вы можете использовать его следующим образом:
article_obj.reactions.all()