[Django]-Django – objects.values() and prefetch_related() in same query

3👍

Instead the values method you can use the only and serialize manually:

from django.db.models import Prefetch
from django.forms import model_to_dict
from django.http import JsonResponse

def books(request):
    prefetch = Prefetch('book_stat_set', queryset=Book_stat.objects.only('like', 'rating'))
    qs = Book.objects.prefetch_related(prefetch).only('id','title', 'image')
    result = []
    for book in qs:
        row = model_to_dict(book, fields=['id','title', 'image'])
        row['image'] = row['image'].url
        stats = []
        for book_stat in book.book_stat_set.all():
            stat = model_to_dict(book_stat, fields=['like', 'rating'])
            stat['rating'] = str(stat['rating'])  # or float(stat['rating']) - depends on your purposes
            stats.append(stat)
        # you can calculate an average rating here
        row['stats'] = stats
        result.append(row)
    return JsonResponse(result)

1👍

If you need it only once you can serialize it by hand.

books = Book.objects.prefetch_related('book_stat_set')

books_json = [{
    'id': book.id,
    'title': book.title,
    'image': book.image.url,
    'stats': [
        {
            'like': stat.like, 'rating': str(stat.rating)
        } for stat in book.book_stat_set.all()
        ]
} for book in books]

Leave a comment