【问题标题】:Serializing Nested foreign key objects序列化嵌套外键对象
【发布时间】:2020-10-22 01:06:58
【问题描述】:

无论谁正在阅读本文,希望您一切顺利。 我正在创建一个社交媒体应用程序,其中包括帖子以及喜欢和 cmets,就像任何其他社交媒体网站一样,我正在尝试通过序列化程序将数据从后端发送到前端,我遇到的问题是我不是能够获得全部数据但部分数据的输出。以下代表我试图序列化的对象的 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')
]
)
  
}

任何线索或帮助或任何策略建议将不胜感激。

【问题讨论】:

    标签: python django serialization django-rest-framework


    【解决方案1】:

    尝试像设置 Liked_by 字段一样设置related_name

    post=models.ForeignKey(Post,on_delete=models.CASCADE, related_name='likes')
    

    不幸的是,django rest 框架掩盖了一些异常,因为它试图捕获其中一些异常,包括AttributeError 以执行字段存在检查。

    【讨论】:

    • 谢谢,它成功了,但我怎样才能将帖子称为喜欢?因为点赞只是帖子的关系?
    • 这里的相关名称似乎令人困惑。请注意,通过指定相关名称,您是在告诉 Django 从另一个方面如何调用关系。您是在告诉 Django 在任何名为 likes 的帖子对象中放置一个字段,以引用相关的喜欢。我还放了一个文档链接。
    【解决方案2】:

    注意事项:

    1. 序列化程序处理数据,而不是序列化程序类。相反,您需要创建 SerializerMethodField() 并为其创建一个 getter。
    2. 为避免请求向数据库发送垃圾邮件问题,请记住将 .select_related() / .prefetch_related() 添加到您的 QuerySet。
    3. 使用小写字段名称被认为是一种很好的做法 :)

    示例:

    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
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-28
      • 1970-01-01
      相关资源
      最近更新 更多