I am still in the same problem. I hope you cooperate in the solution. I want to get the result of this query in Django.
SELECT city_name, MAX(total_places) total_places
FROM(SELECT city city_name, COUNT(city) total_places
FROM Places
GROUP BY 1) t1
GROUP BY 1;
If I look at this answer, it should be something like:
Places.objects.annotate(total=COUNT('city')).latest('total')
Related
I want to get a list of all users who are within a Django Group. For example:
User.objects.filter(group='Staff')
I cannot find how to do this query anywhere in the docs.
The following query solved my problem.
User.objects.filter(groups__name='Staff')
Thanks to #SardorbekImomaliev for figuring it out.
This query allows you to find users by group id rather than by group name:
group = Group.objects.get(id=group_id)
users = group.user_set.all()
Here's a query that lets you search by group name:
users = User.objects.filter(groups_name='group_name')
I've got a working SQL query that I'm trying to write in Django (without resorting to RAW) and was hoping you might be able to help.
Broadly, I'm looking to next two queries - the first calculates a COUNT, and then I'm looking to calculate an AVERAGE of the COUNTS. (this'll give you the average number of items on a ticket, per location)
The SQL that works is:
SELECT location_name, Avg(subq.num_tickets) FROM (
SELECT Count(ticketitem.id) AS num_tickets, location.name AS location_name
FROM ticketitem
JOIN ticket ON ticket.id = ticketitem.ticket_id
JOIN location ON location.id = ticket.location_id
JOIN location ON location.id = location.app_location_id
GROUP BY ticket_id, location.name) AS subq
GROUP BY subq.location_name;
For my Django code, I'm trying something like this:
# Get the first count
qs = TicketItem.objects.filter(<my complicated filter>).\
values('ticket__location__app_location__name','posticket').\
annotate(num_tickets=Count('id'))
# now get the average of the count
qs2 = qs.values('ticket__location__app_location__name').\
annotate(Avg('num_tickets')).\
order_by('location__app_location__name')
but that fails because num_tickets doesn't exist ... Anyway - suspect I'm being slow. Would love someone to enlighten me!
Check out the section on aggregating annotations from the Django docs. Their example takes an average of a count.
I was playing around with this a bit in a manage.py shell, and I think the django ORM might not be able to do that kind of annotation. Honestly you're probably going to have to resort to doing a raw query or bind in something like https://github.com/Deepwalker/aldjemy which would let you do that via SQLAlchemy.
When I playing with this I tried
(my_model.objects.filter(...)
.values('parent_id', 'parent__name', 'thing')
.annotate(Count('thing'))
.values('name', 'thing__count')
.annotate(Avg('thing__count')))
Which gave a lovely traceback about FieldError: Cannot compute Avg('thing__count'): 'thing__count' is an aggregate, which makes sense since I doubt the ORM is trying to convert that first group by to a nested query.
See my model
https://github.com/rg3915/morris/blob/master/myproject/core/models.py
How to return percent 'uf' of total?
Example:
'uf','quant'
'AM',8
'SP',9
'RJ',4
I try
p=Person.objects.values('uf').annotate(quant=Count('uf', distinct=True)).values_list('uf','quant')
print(p.query)
but return
SELECT "core_person"."uf", COUNT(DISTINCT "core_person"."uf") AS "quant" FROM "core_person" GROUP BY "core_person"."uf", "core_person"."first_name" ORDER BY "core_person"."first_name" ASC
and i need
SELECT "core_person"."uf", COUNT(DISTINCT "core_person"."uf") AS "quant" FROM "core_person" GROUP BY "core_person"."uf" ORDER BY "core_person"."uf" ASC
From your example, I'm going to assume that you are looking to retrieve a list of states and the total number of people that belong to that state.
You were pretty close in your attempt, however you were lacking an order_by() that would have let you choose the order field.
As such your query should look like this:
Person.objects.values('uf').annotate(quant=Count('uf')).order_by('uf').values_list('uf','quant')
I hope you'll notice that I have also removed the distinct=True argument from the Count function, as we want to be able to group all of the similar results.
I went through a lot of links and sites , but i can't find the solution for my problem anywhere. So at last i came here .
My problem is that, I want to use the group by clause with the filter query.
i have found this
How to query as GROUP BY in django?
for objects.all() . But could not find anything for objects.filter()
Here is my query
query =Kicthen.objects.filter( cabinets='1').query
query.group_by = ['style_id']
results = QuerySet(query=query, model=Kicthen)
But its return nothing.
I don't want to use any annotate and distinct with it
Use can use raw to make group by
http://doughellmann.com/2007/12/using-raw-sql-in-django.html
I've got this model:
class Visit(models.Model):
timestamp = models.DateTimeField(editable=False)
ip_address = models.IPAddressField(editable=False)
If a user visits multiple times in one day, how can I filter for unique rows based on the ip field? (I want the unique visits for today)
today = datetime.datetime.today()
yesterday = datetime.datetime.today() - datetime.timedelta(days=1)
visits = Visit.objects.filter(timestamp__range=(yesterday, today)) #.something?
EDIT:
I see that I can use:
Visit.objects.filter(timestamp__range=(yesterday, today)).values('ip_address')
to get a ValuesQuerySet of just the ip fields. Now my QuerySet looks like this:
[{'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address':
u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}, {'ip_address': u'127.0.0.1'}]
How do I filter this for uniqueness without evaluating the QuerySet and taking the db hit?
# Hope it's something like this...
values.distinct().count()
What you want is:
Visit.objects.filter(stuff).values("ip_address").annotate(n=models.Count("pk"))
What this does is get all ip_addresses and then it gets the count of primary keys (aka number of rows) for each ip address.
With Alex Answer I also have the n:1 for each item. Even with a distinct() clause.
It's weird because this is returning the good numbers of items :
Visit.objects.filter(stuff).values("ip_address").distinct().count()
But when I iterate over "Visit.objects.filter(stuff).values("ip_address").distinct()" I got much more items and some duplicates...
EDIT :
The filter clause was causing me troubles. I was filtering with another table field and a SQL JOIN was made that was breaking the distinct stuff.
I used this hint to see the query that was really used :
q=Visit.objects.filter(myothertable__field=x).values("ip_address").distinct().count()
print q.query
I then reverted the class on witch I was making the query and the filter to have a join that doesn't rely on any "Visit" id.
hope this helps
The question is different from what the title suggests. If you want set-like behavior from the database, you need something like this.
x = Visit.objects.all().values_list('ip_address', flat=True).distinct()
It should give you something like this for x.
[1.2.3.4, 2.3.4.5, ...]
Where
len(x) == len(set(x))
Returns True