【问题标题】:Python Django saved posts computed methodPython Django 保存帖子计算方法
【发布时间】:2020-12-26 01:36:25
【问题描述】:

假设我使用默认的 django 模型、一个 Post 模型(下面的代码)和一个将用户链接到 Post 的 SavedPost 模型(如果存在具有特定帖子的特定用户,则为该用户保存该帖子)和链接 2 个用户的追随者模型(类似于 SavedPost)。

我想要做什么:一个 API,对于用户来说,他们可以获取他们关注的用户的所有帖子,此外,这些帖子中的每一个都有一个额外的“字段”来说明该帖子是否被保存。

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_type = models.CharField(max_length=1, choices=[('B', 'Blog'), ('V', 'Video')], default='B')
    file_path = models.URLField(null=True)
    title = models.CharField(max_length=255)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

class SavedPost(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # A user can save a post only once.
        unique_together = ('user', 'post')

class Follower(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
    follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follower")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # A user can follow another user only once
        unique_together = ('user', 'follower')

后序列化器:

class PostSerializer(serializers.ModelSerializer):
    """
    Nested serializer for post using SimpleUser and Kingdom.
    """

    class Meta:
        model = Post
        fields = ('id', 'user', 'post_type', 'file_path',
                  'title', 'description', 'created_at', 'updated_at')

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['user'] = UserSerializer(
            User.objects.get(pk=data['user'])).data
        return data

API 视图:

@permission_classes([IsAuthenticated,])
@api_view(['GET'])
def get_following(request):
    user = request.user
    following = Follower.objects.filter(follower=user).values('user')
    # saved_posts = SavedPost.objects.filter(user=user, post__user__in=following).order_by('-post__created_at')
    posts = Post.objects.filter(user__in=following).order_by('-created_at')

    serializer = PostSerializer(posts, many=True, context={'request': request})
    return JsonResponse(serializer.data, safe=False)

到目前为止,通过我所做的视图,我可以获得 request.user 关注的所有帖子,但它没有说明它们是否被保存。我正在寻找在帖子上说“is_saved”布尔值来说明该帖子是否为该用户保存。

对此的任何帮助/方法表示赞赏。谢谢。

【问题讨论】:

  • 你能添加PostSerializer序列化器吗?
  • 添加了 PostSerializer!

标签: python django api serialization model


【解决方案1】:

首先,为了清楚起见,我将为ForeignKeys 在SavedPost 中定义related_name 选项-由您决定是否实施:

class SavedPost(models.Model):
    user = models.ForeignKey(User, related_name="saved", on_delete=models.CASCADE)
    post = models.ForeignKey(Post, related_name="saved", on_delete=models.CASCADE)
    ...

现在,在您的 PostSerializer 中,您可以添加此字段(请记住将其添加到 Meta 内部类中的 fields 变量 - 如果您使用的是 ModelSerializer):

class PostSerializer(serializers.ModelSerializer):
    saved = SavedPostSerializer(many=True)
    ...

要完成它,如果在同一个文件/模块中,请定义您的 SavedPostSerializer - 以上 PostSerializer

class SavedPostSerializer(serializers.ModelSerializer):
    class Meta:
        model = SavedPost
        fields = "__all__"

有了这个,你的 json 应该有一个带有 saved 键的嵌套字段,其中包含 SavedPosts 的数组,如果有任何与检索到的 Posts 相关的话。

【讨论】:

  • 我明白你的意思。有没有办法使 PostSerializer 中的“已保存”属性成为布尔值?如果有已保存的帖子则为 true,否则为 false。
  • 在这种情况下,也许您可​​以覆盖PostSerializer 中的to_representation,并根据saved 列表中是否有任何元素来分配其值;例如bool(data["saved"]).
【解决方案2】:

使用 serializers.SerializerMethodField 作为

class PostSerializer(serializers.ModelSerializer):
    is_saved = serializers.SerializerMethodField()

    def get_is_saved(self, post_instance):
        return SavedPost.objects.filter(user=post_instance.user, post=post_instance).exists()

    class Meta:
        model = Post
        fields = ['id', 'user', 'post_type', 'file_path',
                  'title', 'description', 'created_at', 'updated_at', 'is_saved']

    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['user'] = UserSerializer(
            User.objects.get(pk=data['user'])).data
        return data

【讨论】:

  • 这行得通,应该将缺少“is_saved”的一件事添加到字段中。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
  • 2022-11-22
  • 2022-01-02
相关资源
最近更新 更多