Count and group by foreign key and return model django
up vote
1
down vote
favorite
Data Model:
- Each
Libraryhas manyBooks - Each
Bookmay or may not be read by aUserdictated by theUserBookReceipt
Objective:
Given a user, order the libraries by how many books they have read at each library.
Example:
User 1 has read:
- 2 Books from Library 1
- 5 Books from Library 2
- 1 Book from Library 3
- 0 Books from Library 4
We should return the libraries in order of number of books read by User 1 ie:
Library 2, Library 1, Library 3
Current solution
libraries = (UserBookReceipt.objects
.filter(user=user)
.values('book__library')
.annotate(rcount=Count('book__library'))
.order_by('-rcount')
)
Actual output
[
{'book_library': 2, 'rcount': 5},
{'book_library': 1, 'rcount': 2},
{'book_library': 3, 'rcount': 1}
]
Expected output
[
{'book_library': <Library: 2>, 'rcount': 5},
{'book_library': <Library: 1>, 'rcount': 2},
{'book_library': <Library: 3>, 'rcount': 1}
]
The actual output is 90% of what I want, except I want the book_library value to be instances of the django Library model rather than just the library id. Otherwise, I have to make another query to retrieve the Library objects which would probably require some inefficient ids__in query.
How can I count and group by the UserBookReceipt.book__library and return the Library model?
If I were to do this in SQL the query would look like
with rcount_per_lib as (
select lib.id, count(*) as rcount
from lib, books, user_book_receipts
where user_book_receipts.book_id = books.id
and lib.id = books.lib_id
and user_book_receipts.user_id = 1
group by lib.id)
select lib.*, rcount from rcount_per_lib
where lib.id = rcount_per_lib.id
order by rcount
python sql django postgresql
add a comment |
up vote
1
down vote
favorite
Data Model:
- Each
Libraryhas manyBooks - Each
Bookmay or may not be read by aUserdictated by theUserBookReceipt
Objective:
Given a user, order the libraries by how many books they have read at each library.
Example:
User 1 has read:
- 2 Books from Library 1
- 5 Books from Library 2
- 1 Book from Library 3
- 0 Books from Library 4
We should return the libraries in order of number of books read by User 1 ie:
Library 2, Library 1, Library 3
Current solution
libraries = (UserBookReceipt.objects
.filter(user=user)
.values('book__library')
.annotate(rcount=Count('book__library'))
.order_by('-rcount')
)
Actual output
[
{'book_library': 2, 'rcount': 5},
{'book_library': 1, 'rcount': 2},
{'book_library': 3, 'rcount': 1}
]
Expected output
[
{'book_library': <Library: 2>, 'rcount': 5},
{'book_library': <Library: 1>, 'rcount': 2},
{'book_library': <Library: 3>, 'rcount': 1}
]
The actual output is 90% of what I want, except I want the book_library value to be instances of the django Library model rather than just the library id. Otherwise, I have to make another query to retrieve the Library objects which would probably require some inefficient ids__in query.
How can I count and group by the UserBookReceipt.book__library and return the Library model?
If I were to do this in SQL the query would look like
with rcount_per_lib as (
select lib.id, count(*) as rcount
from lib, books, user_book_receipts
where user_book_receipts.book_id = books.id
and lib.id = books.lib_id
and user_book_receipts.user_id = 1
group by lib.id)
select lib.*, rcount from rcount_per_lib
where lib.id = rcount_per_lib.id
order by rcount
python sql django postgresql
3
If you are going to use SQL, you should really to use proper, explicit, standardJOINsyntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theandsyntax is equivalent performance wise toINNER JOIN
– david_adler
Nov 17 at 14:36
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
Data Model:
- Each
Libraryhas manyBooks - Each
Bookmay or may not be read by aUserdictated by theUserBookReceipt
Objective:
Given a user, order the libraries by how many books they have read at each library.
Example:
User 1 has read:
- 2 Books from Library 1
- 5 Books from Library 2
- 1 Book from Library 3
- 0 Books from Library 4
We should return the libraries in order of number of books read by User 1 ie:
Library 2, Library 1, Library 3
Current solution
libraries = (UserBookReceipt.objects
.filter(user=user)
.values('book__library')
.annotate(rcount=Count('book__library'))
.order_by('-rcount')
)
Actual output
[
{'book_library': 2, 'rcount': 5},
{'book_library': 1, 'rcount': 2},
{'book_library': 3, 'rcount': 1}
]
Expected output
[
{'book_library': <Library: 2>, 'rcount': 5},
{'book_library': <Library: 1>, 'rcount': 2},
{'book_library': <Library: 3>, 'rcount': 1}
]
The actual output is 90% of what I want, except I want the book_library value to be instances of the django Library model rather than just the library id. Otherwise, I have to make another query to retrieve the Library objects which would probably require some inefficient ids__in query.
How can I count and group by the UserBookReceipt.book__library and return the Library model?
If I were to do this in SQL the query would look like
with rcount_per_lib as (
select lib.id, count(*) as rcount
from lib, books, user_book_receipts
where user_book_receipts.book_id = books.id
and lib.id = books.lib_id
and user_book_receipts.user_id = 1
group by lib.id)
select lib.*, rcount from rcount_per_lib
where lib.id = rcount_per_lib.id
order by rcount
python sql django postgresql
Data Model:
- Each
Libraryhas manyBooks - Each
Bookmay or may not be read by aUserdictated by theUserBookReceipt
Objective:
Given a user, order the libraries by how many books they have read at each library.
Example:
User 1 has read:
- 2 Books from Library 1
- 5 Books from Library 2
- 1 Book from Library 3
- 0 Books from Library 4
We should return the libraries in order of number of books read by User 1 ie:
Library 2, Library 1, Library 3
Current solution
libraries = (UserBookReceipt.objects
.filter(user=user)
.values('book__library')
.annotate(rcount=Count('book__library'))
.order_by('-rcount')
)
Actual output
[
{'book_library': 2, 'rcount': 5},
{'book_library': 1, 'rcount': 2},
{'book_library': 3, 'rcount': 1}
]
Expected output
[
{'book_library': <Library: 2>, 'rcount': 5},
{'book_library': <Library: 1>, 'rcount': 2},
{'book_library': <Library: 3>, 'rcount': 1}
]
The actual output is 90% of what I want, except I want the book_library value to be instances of the django Library model rather than just the library id. Otherwise, I have to make another query to retrieve the Library objects which would probably require some inefficient ids__in query.
How can I count and group by the UserBookReceipt.book__library and return the Library model?
If I were to do this in SQL the query would look like
with rcount_per_lib as (
select lib.id, count(*) as rcount
from lib, books, user_book_receipts
where user_book_receipts.book_id = books.id
and lib.id = books.lib_id
and user_book_receipts.user_id = 1
group by lib.id)
select lib.*, rcount from rcount_per_lib
where lib.id = rcount_per_lib.id
order by rcount
python sql django postgresql
python sql django postgresql
edited Nov 17 at 15:31
asked Nov 17 at 14:29
david_adler
2,18722045
2,18722045
3
If you are going to use SQL, you should really to use proper, explicit, standardJOINsyntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theandsyntax is equivalent performance wise toINNER JOIN
– david_adler
Nov 17 at 14:36
add a comment |
3
If you are going to use SQL, you should really to use proper, explicit, standardJOINsyntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theandsyntax is equivalent performance wise toINNER JOIN
– david_adler
Nov 17 at 14:36
3
3
If you are going to use SQL, you should really to use proper, explicit, standard
JOIN syntax.– Gordon Linoff
Nov 17 at 14:30
If you are going to use SQL, you should really to use proper, explicit, standard
JOIN syntax.– Gordon Linoff
Nov 17 at 14:30
1
1
Why? AFAIK the
and syntax is equivalent performance wise to INNER JOIN– david_adler
Nov 17 at 14:36
Why? AFAIK the
and syntax is equivalent performance wise to INNER JOIN– david_adler
Nov 17 at 14:36
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
You need to change how you approach the queryset. Use Library rather than UserBookReceipt.
libraries = (Library.objects
.filter(book__userbookreceipt__user=user)
.annotate(rcount=Count('book__userbookreceipt', distinct=True))
.order_by('-rcount')
)
[x.rcount for x in libraries]
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
You need to change how you approach the queryset. Use Library rather than UserBookReceipt.
libraries = (Library.objects
.filter(book__userbookreceipt__user=user)
.annotate(rcount=Count('book__userbookreceipt', distinct=True))
.order_by('-rcount')
)
[x.rcount for x in libraries]
add a comment |
up vote
2
down vote
accepted
You need to change how you approach the queryset. Use Library rather than UserBookReceipt.
libraries = (Library.objects
.filter(book__userbookreceipt__user=user)
.annotate(rcount=Count('book__userbookreceipt', distinct=True))
.order_by('-rcount')
)
[x.rcount for x in libraries]
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
You need to change how you approach the queryset. Use Library rather than UserBookReceipt.
libraries = (Library.objects
.filter(book__userbookreceipt__user=user)
.annotate(rcount=Count('book__userbookreceipt', distinct=True))
.order_by('-rcount')
)
[x.rcount for x in libraries]
You need to change how you approach the queryset. Use Library rather than UserBookReceipt.
libraries = (Library.objects
.filter(book__userbookreceipt__user=user)
.annotate(rcount=Count('book__userbookreceipt', distinct=True))
.order_by('-rcount')
)
[x.rcount for x in libraries]
edited 2 days ago
david_adler
2,18722045
2,18722045
answered Nov 17 at 15:51
schillingt
4,88211620
4,88211620
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53352158%2fcount-and-group-by-foreign-key-and-return-model-django%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
If you are going to use SQL, you should really to use proper, explicit, standard
JOINsyntax.– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK the
andsyntax is equivalent performance wise toINNER JOIN– david_adler
Nov 17 at 14:36