django database functions cumulative count? - django

is their a way to create cumulative count using/customizing django database functions. this built-in query gets the number of items for each year. what if we need the number of items before that year ?
items.values('year').annotate(nb=Count('id'))

This functionality is built-in in django. You can combine order_by, values and annotate to get what you want:
Item.objects.order_by('year').values('year').annotate(nb=Count('id'))
For the official docs, see: aggregation. If the sample doesn't work I'll need more information about the model to give you the correct call. Please provide the full model and, if required, some sample data.

Related

Django filtering with F and Q operations

I have a model class in my django project:
*user_id
*amount
*net_balance
*created_on
I have a list of user_ids(let's say 3). I need to get the last row for each user_id and then do some operation and create a new row for each user id. How do this efficiently. I can certainly do 6 transactions (if there are 3 items in list of userids).
If you want the most recent entry then
YourModel.objects.filter(user=user_id).latest('created_on')
If I understand your question correctly then you need to get all the user_ids (presumably you have a separate User model?) and then loop through them - for each user getting the most recent entry and then create the new row.
You need 1 select (at least) for all the records you interested and 1 insert query for each record returned.
The select query can be generated by ORM abilities (aggregation) or you can use raw SQL if you fill comfortable. If you use PostgreSQL, you can use distinct ability (I recommended) as:
Model.objects.order_by('user_id', '-created_on').distinct('user_id')
or you can use aggregation abilities as:
Model.objects.filter(user_id__in=[1,2,3]).values('user_id', 'created_on').annotate(last_row=Max('created_on')).filter(created_on=F('last_row'))
The correct answer depends on your Django version and database. But there are lots of good features in Django to achieve this kind of stuffs.

how to count number usage of a tag? django with taggableManager

I am currently using taggableManager as my tags in django. I can see in admin what is currently using the tag but then is there a way to count them?
let's say I have the follow tag and as can see there are a 4 objects using this tag. how can I get the count of 4 for this tag?
Thanks in advance
You will want to do a typical query on your database for the count of rows for a particular tag. Instead of looking at the len of a queryset there is another count feature less commonly known in Django which gives you the count number from SQL as opposed to having to query the entire database just to get the length.
len(). A QuerySet is evaluated when you call len() on it. This, as you
might expect, returns the length of the result list.
Note: If you only need to determine the number of records in the set
(and don’t need the actual objects), it’s much more efficient to
handle a count at the database level using SQL’s SELECT COUNT(*).
Django provides a count() method for precisely this reason.
https://docs.djangoproject.com/en/1.11/ref/models/querysets/

How to write the query for this requirement?

I have several hundred thousand svn commit record in my django database, each record save the related info of each commit(like BugID,LinesChanged,SubmitWeek ...)
I want to summary each field info of the records and create the report according to the SubmitWeek field like the following :
I iterate the records and operate the related field value currently , I want to know if there is a more succinct way to define the query and extract the summary? Many thanks
Your question is a bit vague.
If you are looking for a way to form your queries more specific to make Django do more joins and less separate queries, have a look at:
values() and values_list() of the QueryManager
If you want to make Django fetch related objects at once and not in separate queries, have a look at:
prefetch_related() and select_related()
If you want to update data more efficiently, have a look at:
F() https://docs.djangoproject.com/en/1.9/ref/models/expressions/#django.db.models.F
refer to the manual , I used the following statements and it seems works well , thanks Risadinha anyway :)
# Sum all the records's LinesChanged value
SVN_Commit.objects.filter(my filter).aggregate(Sum('LinesChanged'))
# Get the unique SubmitWeek List
SVN_Commit.objects.filter(my filter).values_list('SubmitWeek', flat=True).order_by('SubmitWeek').distinct()

mongoengine +django how to count the number of items of same content

I want to count all the numbers of different values in a field.there is no "annotate()" to use in mongoengine ,then how could i count the number and order them by numbers
The only way i thought out to solve this is use"distinct()"to find out the different values and then use "count()"to count each of the values
it's a stupid way to realize the result i want
Do you have any other ways ?
MongoEngine has some map reduce helpers that should meet your needs. The Queryset method item_frequencies[1] will meet your needs. There isnt any special support for the new aggregation framework but support could be added in the future.
Example usage:
BlogPost.objects.item_frequencies('tags')
[1] http://docs.mongoengine.org/en/latest/apireference.html?highlight=item_frequencies#mongoengine.queryset.QuerySet.item_frequencies
MongoEngine itself has no special means to achieve this, but the MongoDB 2.2 aggregation framework lets you count documents, grouped by a field. I suggest using PyMongo's aggregate method directly with an aggregation pipeline to do this query:
http://api.mongodb.org/python/current/examples/aggregation.html

Mathematical Operations on Django Annotations

I have a Django model that defines a TimeSlot. Each TimeSlot can hold a certain number of users (TimeSlot.spots). Each TimeSlot also has a certain number of users already held in it (a many to many field, TimeSlot.participants.
When I pass to the template that displays the available TimeSlots to the user, I annotate with TimeSlot.objects.annotate(Count('participants')),which gives the number of users currently held by the TimeSlot as participants__count.
However, what I really want is the number of spots remaining, the capacity (TimeSlot.spots) minus the number currently held (participants__count). How can I annotate another field with this new number, so I can pass it to the template?
It's still not possible with annotation (though it is planned to implement in Django). But you can do it with an .extra() query. See my answer to another question for details.
Upd.:
Essentially, you need somethig like this query:
items = MyModel.objects.extra(
select = {'variance': 'Model.someField - SUM(relatedModel__someField)'},
)
Not possible with only an annotation. I'd create a method on the model which does the annotation, and then subtract that from your TimeSlot.spots value. This will use more database queries, but thats your only option. Or I guess you could drop down to raw SQL...