Django prefetch_related with limit

后端 未结 3 815
情歌与酒
情歌与酒 2020-12-05 09:40

Is there a way to tell prefetch_related to only fetch a limited set of related objects? Lets say I am fetching a list of users and I know I want to fetch their

相关标签:
3条回答
  • 2020-12-05 10:19

    The only way to limit the number of prefetched related objects seems to be using Prefetch() and filtering on fileds. Using sliceing

    User.objects.all().prefetch_related(
        Prefetch('msg_sent', queryset=UserMsg.objects.order_by('-created')[:10]))
    

    returns an error

    AssertionError: Cannot filter a query once a slice has been taken.
    

    The only way to limit the number of related objects seems to be using filter on a value, for example

    from datetime import datetime, timedelta
    timelimit = datetime.now() - timedelta(days=365)
    
    User.objects.all().prefetch_related(
        Prefetch('msg_sent', queryset=UserMsg.objects.filter(created__gte=timelimit)))
    

    While that doesn't return a fixed number, in may be useful in some situation, and it will reduce the number of prefetched objects.

    0 讨论(0)
  • 2020-12-05 10:22

    I think there is a workaround now to in django new version as we have OuterRef and Subquery.

    from django.db.models import OuterRef, Subquery, Prefetch
    
    subqry = Subquery(Comment.objects \
        .filter(user_id=OuterRef('user_id')) \
        .values_list('id', flat=True)[:5])
    
    User.objects.prefetch_related(
        Prefetch('comments', queryset=Comment.objects.filter(id__in=subqry)))
    
    0 讨论(0)
  • 2020-12-05 10:34

    thats what actually works for me django(2.1) (based on haseebahmad answer).
    in order for prefetch_related to accept customize queryset: Prefetch
    so:
    from django.db.models import OuterRef, Subquery ,Prefetch

    User.objects.all().prefetch_related(Prefetch('comment_set',  
    queryset=Comment.objects.filter(id__in= 
    Subquery(Comment.objects.filter(user_id=OuterRef('user_id')).
    values_list('id', flat=True)[:1]))))
    
    0 讨论(0)
提交回复
热议问题