简体   繁体   中英

How to annotate over multiple django models

I have the following Django models:

class Book(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200)

    class Meta:
        db_table = "books"

class BookCategory(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)

    class Meta:
        db_table = "bookcategories"

class BookCategoryMembership(models.Model):
    id = models.AutoField(primary_key=True)
    category = models.ForeignKey(BookCategory)
    book = models.ForeignKey(Book)

    class Meta:
        db_table = "bookcategories_books"

class UserBook(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
    book = models.ForeignKey(Book)

    class Meta:
        db_table = "user_book"

The UserBook model is used to denote if a user owns a book.

Now, I want to return the list of all book categories, ordered by the number of most owned books (ie the most popular categories should come up first).

I tried with Django ORM annotations, but I did not get it to work.

This is the subquery which does not work:

BookCategoryMembership.objects.annotate(num_books=Count("book__userbook")).
values('category_id').annotate(Sum('num_books'))

(resulting in the error message

FieldError: Cannot compute Sum('num_books'): 'num_books is an aggregate"

I know that from this subquery, the order_by clause is still missing, but I assume I have to get the subquery to work first.

Do you know with which query I can solve this problem in django? I want to avoid splitting it up into multiple queries or doing any computations in django.

您可以使用RawSQL('any raw expression', ())作为解决方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM