Count and group by foreign key and return model django
up vote
1
down vote
favorite
Data Model:
- Each
Library
has manyBook
s - Each
Book
may or may not be read by aUser
dictated 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
Library
has manyBook
s - Each
Book
may or may not be read by aUser
dictated 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, standardJOIN
syntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theand
syntax 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
Library
has manyBook
s - Each
Book
may or may not be read by aUser
dictated 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
Library
has manyBook
s - Each
Book
may or may not be read by aUser
dictated 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, standardJOIN
syntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theand
syntax 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, standardJOIN
syntax.
– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK theand
syntax 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
JOIN
syntax.– Gordon Linoff
Nov 17 at 14:30
1
Why? AFAIK the
and
syntax is equivalent performance wise toINNER JOIN
– david_adler
Nov 17 at 14:36