#python #django #serialization #django-rest-framework
#python #django #сериализация #django-rest-framework
Вопрос:
кто бы ни читал это, надеюсь, у вас все хорошо. Я создаю приложение для социальных сетей, которое включает в себя пост, лайки и комментарии, как и любой другой сайт в социальных сетях, я пытаюсь отправить данные из своего бэкэнда во внешний интерфейс через сериализаторы, проблема, с которой я сталкиваюсь, заключается в том, что я не могу получить вывод целых данных, но частичныйданные. Следующее представляет мой models.py для объектов, которые я пытаюсь сериализовать
models.py
class User(AbstractUser):
contact_no = models.CharField(max_length=15,null=True,blank=True)
profile_picture=models.ImageField(upload_to=to_upload,default="defaultprofile.jpg")
class Post(models.Model):
posted_by=models.ForeignKey(User,on_delete=models.CASCADE)
date= models.DateField(auto_now=True)
time=models.TimeField(auto_now=True)
content=models.CharField(max_length=2000)
media=models.ImageField(default=None,blank=True,upload_to=to_upload_post)
class Like(models.Model):
Liked_by=models.ForeignKey(User,on_delete=models.CASCADE,related_name="likes")
post=models.ForeignKey(Post,on_delete=models.CASCADE)
date = models.DateField(auto_now=True)
time = models.TimeField(auto_now=True)
и сериализаторы, которые я использую, это
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model=User
fields=['id','username','first_name','last_name','profile_picture']
class LikeSerializer(serializers.ModelSerializer):
Liked_by=UserSerializer()
class Meta:
model=Like
fields=['Liked_by']
class PostSerializer(serializers.ModelSerializer):
posted_by=UserSerializer()
likes=LikeSerializer(many=True)
class Meta:
model=Post
fields=['posted_by','id','content','date','time','media','likes']
Это не вызывает никаких ошибок при импорте, но не дает полных данных.
Результат, который я получаю, это
{
'posted_by':
OrderedDict([
('id', 7),
('username', 'user'),
('first_name', ''),
('last_name', ''),
('profile_picture', '/media/defaultprofile.jpg')]),
'id': 4,
'content': 'This is a test post for likes',
'date': '2020-10-22',
'time': '05:34:55.979863',
'media': None
}
но то, что я пытаюсь получить, это
Желаемый результат
{
'posted_by':
OrderedDict([
('id', 7),
('username', 'user'),
('first_name', ''),
('last_name', ''),
('profile_picture', '/media/defaultprofile.jpg')]),
'id': 4,
'content': 'This is a test post for likes',
'date': '2020-10-22',
'time': '05:34:55.979863',
'media': None
'likes':
['Liked_by':
OrderedDict([
('id', 1),
('username', 'user1'),
('first_name', ''),
('last_name', ''),
('profile_picture', '/media/defaultprofile.jpg')
]
)
}
Любые рекомендации или рекомендации по стратегии будут высоко оценены.
Ответ №1:
Попробуйте установить related_name так же, как вы сделали для поля Liked_by:
post=models.ForeignKey(Post,on_delete=models.CASCADE, related_name='likes')
К сожалению, некоторые исключения маскируются фреймворком django rest, поскольку он пытается перехватить некоторые из них, в том числе AttributeError
для выполнения проверок существования полей.
Комментарии:
1. Спасибо, это сработало, но как я могу ссылаться на сообщение как на лайки? поскольку лайки — это просто связь сообщений?
2. Кажется, что связанное имя здесь сбивает с толку. Пожалуйста, обратите внимание, что, указывая связанное имя, вы сообщаете Django, как вызывать отношение с другой стороны. Вы говорите Django поместить поле в любой объект post с именем
likes
для ссылки на связанные лайки. Я также поместил ссылку на документацию.
Ответ №2:
Несколько вещей, на которые следует обратить внимание:
- сериализаторы работают с данными, а не с классами сериализаторов. Вместо этого вам нужно создать SerializerMethodField() и создать для него средство получения.
- Чтобы избежать проблемы со спамом базы данных с запросами, не забудьте добавить .select_related() / .prefetch_related() в ваш набор запросов.
- Считается хорошей практикой использовать имена полей в нижнем регистре 🙂
пример:
class LikeSerializer(serializers.ModelSerializer):
Liked_by = serializers.SerializerMethodField()
class Meta:
model=Like
fields=['Liked_by']
def get_Liked_by(self, instance):
return UserSerializer(instance.Liked_by, many=False).data