Add a boolean field if a row exists in another table?

若如初见. 提交于 2019-12-06 14:30:17

Piggybacking off of dydek's answer here.

You overwrite your get_queryset in the Api View

class PostList(generics.ListAPIView):
    ...
    def get_queryset(self):
        Post.objects.all().extra(select={
        'current_user_replies_count': 'SELECT COUNT(*) FROM <reply table> WHERE' +
        'post_id=posts_post.id AND owner_id = %s'
                                  },select_params=(request.user.id,))

This will add 'current_user_replies_count' as a property to the Post objects in your queryset.

The next problem here is to many sql queries when you'll be fetching eg. 100 objects (you will have BASE_QUERIES_COUNT + len(objects) ). Of corse we don't want to have linear sql queries count, and this situation should never happen, especially in production version. The perfect solution here would be if we would be able to have all data fetched in one sql query. This is possible with override get_queryset method ( here https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/generics.py#L47 ). And then queryset could look like below, param current_user_replies_count is available as normal model instance variable.

# all only for example
Post.objects.all().extra(select={
        'current_user_replies_count': 'SELECT COUNT(*) FROM <reply table> WHERE '+
                                      'post_id=posts_post.id AND owner_id = %s'
    },
    select_params=(request.user.id,)
)

I haven't tested it, so use it more as example instead of ready solution, and you should cast current_user_replies_count to bool.

You can add custom fields to your PostSerializer

class PostSerializer(serializers.ModelSerializer):
    replied = serializers.SerializerMethodField('has_replies')

    def has_replies(post):
        return post.replies.filter(owner=self.context["request"].user).exists()

    class Meta:
        fields = ('id', 'name', 'replied')
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!