如何使用 Django 高效地检索社交媒体应用程序中的用户提要

问题描述 投票:0回答:1

我是编程新手,也是 Django 新手,我正在尝试设计我的第一个社交媒体应用程序。我想看看是否有一种有效的方法来检索用户提要,从而可以快速检索用户提要,而无需对数据库进行大量操作。我想了解构建高效 API 视图时应遵循的最佳实践。

下面提供的是我当前的用户模型、关注模型和用于检索用户源的 API 视图。我想知道我可以对当前的实现进行哪些改进,以便我可以更多地了解 Django 以及如何构建高效的应用程序。

目前,我的 API 视图检索请求用户关注的所有用户,然后检索这些用户发布的帖子。但是,如果用户关注很多人,则获取请求用户关注的所有用户列表的查询可能效率低下,至少我这么认为。是否有更好的实现来执行,以便我可以获得在数据库检索方面不会密集的用户源?

我有以下用户模型

class User(AbstractUser):
# Additional fields for user profiles
profile_picture = models.ImageField(upload_to='profiles/', null=True, blank=True)  # Profile picture for the user
bio = models.TextField(max_length=300, blank=True)  # Short bio or description for the user
contact_information = models.CharField(max_length=100, blank=True)  # Contact information for the user
profile_privacy = models.CharField(max_length=10, choices=[('public', 'Public'), ('private', 'Private')], default='public')  # Privacy setting for user profile
num_followers = models.PositiveIntegerField(default=0)  # counter to keep track of users num of followers
num_following = models.PositiveIntegerField(default=0)  # counter to keep track of num of users a user is following
num_posts = models.PositiveIntegerField(default=0)  # counter to keep track of num of posts made by the user

我有一个关注模型

class Follow(models.Model):
FOLLOW_STATUS_CHOICES = [
    ('pending', 'Pending'),
    ('accepted', 'Accepted'),
]

follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following')  # ForeignKey User that is following another User
following = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follower')  # ForeignKey User that is being followed by another User
follow_status = models.CharField(max_length=10, choices=FOLLOW_STATUS_CHOICES, default='pending')

class Meta:
    unique_together = ('follower', 'following')  # Ensure unique follower-following pairs
    indexes = [
        models.Index(fields=['follower', 'following', 'follow_status']),  # Combined index
    ]

下面是我目前使用 API 视图检索用户提要的实现

# API view to get posts from the users that the current user follows
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def user_feed(request):
    # Obtains all the users the requesting user is following
    following_users = User.objects.filter(follower__follower=request.user, follower__follow_status='accepted')

    # Set a default page size of 20 returned datasets per page
    default_page_size = 20
    # Utility function to get current page number and page size from the request's query parameters and calculate the pagination slicing indeces
    start_index, end_index, validation_response = get_pagination_indeces(request, default_page_size)
    if validation_response:
        return validation_response

    # fetch the posts from the users in following_users
    feed_posts = Post.objects.filter(user__in=following_users)[start_index:end_index]

    # The context is used to pass the request to the PostSerializer to perform custom logic
    serializer = PostSerializer(feed_posts, many=True, context={'request': request})

    return Response(serializer.data, status=status.HTTP_200_OK)

我目前的方法有效,但我只是想知道它是否可以更好

django django-models django-rest-framework django-views social-networking
1个回答
0
投票

无需先检索

following_users
,可以直接使用:

进行过滤
feed_posts = Post.objects.filter(
    user__follower__follower=request.user, follower__follow_status='accepted'
)

自己实现分页或自己实例化序列化器可能也不是一个好主意。这一切都可以通过

ListAPIView
 [drf-doc] 来完成,它已经过更广泛的测试,因此不太可能包含错误:

class UserFeedListAPIView(ListAPIView):
    permission_classes = [IsAuthenticated]
    serializer_class = PostSerializer
    queryset = Post.objects.all()

    def get_queryset(self):
        return (
            super()
            .get_queryset()
            .filter(
                user__follower__follower=request.user,
                follower__follow_status='accepted',
            )
        )

然后您可以注入自定义分页器,但这些设置也可以应用于所有视图,这可能是一个更好的主意,因为这引入了一致性。您可以在 Django Rest Framework 文档分页部分阅读更多相关信息。例如,如果未排序,分页器也会对查询集进行排序。在这种情况下,例如通过主键。这是必要的,否则查询同一页面可能会产生不同的结果,因此“下一页”本身不会是下一页。

© www.soinside.com 2019 - 2024. All rights reserved.