Django count by group - django

I need to create a report in which I can get the value for each month of the year.
models.py
class Ask(models.Model):
team = models.CharField(max_length=255)
date = models.DateField()
In team are only three possible values: A, B, C.
How do I calculate how many times a month was added individual team?
I would like to generate a report for each year.

I suggest you to add month field to your model and pass there month on save. This is help you to run this:
from django.db.models import Count
Ask.objects.filter(date__year='2013').values('month', 'team').annotate(total=Count('team'))
Other method is to use extra parameter and extract month from date field:
from django.db.models import Count
Ask.objects.filter(date__year='2013').extra(select={'month': "EXTRACT(month FROM date)"}).values('month', 'team').annotate(Count('team'))
but EXTRACT method is database dependent and for example dont`t work in SQLite

Related

Django | Get count of articles per month

I got two models Article and Author implemented like this:
class Author(models.Model):
name = models.CharField(max_length=50)
class Article(models.Model):
name = models.CharField(max_length=50)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
pub_date = models.DateField()
On my template I want to plot a graph (using chart.js on the frontend side) showing the authors publications per month, for the last 12 months. For that I need the count of articles published each month.
This is the query to get the authors articles:
articles = Article.objects.filter(author=author)
What would be best practice to get the count per month?
I've thought about annotating each of the twelve month separately to the QuerySet, but haven't found a way that works for me.
Alternatively, I thought about dealing with this on the JS site in the users browser.
Any suggestions/recommendations?
If you need to group data in Django you'll need to use ORM aggregation features.
And to use that on dates you can leverage their ORM helper functions.
from django.db.models.functions import TruncMonth
from django.db.models import Count
Article.objects
.filter(author=author) # Filter by the author
.annotate(month=TruncMonth('created')) # Truncate by month and add 'month' to values
.values('month') # Group By month
.annotate(count_id=Count('id')) # Count the number of articles in the grouping
.order_by('-month')[:12] # Sort by months in descending order (latest to earliest) and get the 12 first results

Count different values of user over a period of time with selecting the latest for that day

I was trying to get models value over a period of time in django. The model is used to keep kind of activity log.
class Activity(models.Model):
PLACE_CHOICES = (('home', 'Home'),('office', 'Office'))
userId = models.IntegerField()
date = models.DateField()
place = models.CharField(max_length=25, choices=PLACE_CHOICES)
An user can have multiple place for a day ('place' can be duplicate) but I need only the latest model for that day.
I need to group data over a period of time (say 15 days) for multiple user, filtering args are something like this,
Activity.objects.filter(userId__in=[1,2], date__gte='2022-01-01', date__lte='2022-01-15')
This is only to show the filtering. I tried other methods,like-
Activity.objects.filter(
userId__in=[1,2], date__gte='2022-01-01', date__lte='2022-01-15'
).annotate(
home=Count('place', distinct=True, filter=Q(place='home'),
office=Count('place', distinct=True, filter=Q(place='home')
).values('userId','home','office')
I need values like this
[{userId:1, home:4, office:3},{userId:2, home:1, office:3}]

How to order by values in ArrayList in Django?

I have a model lets say products, which has a field prices that is basically an array:
prices = [price on Monday, price on Tuesday, price on Thursday]
How do I order products by prices on a specific day, eg: price on Monday?
I assume your prices field is an ArrayField of DecimalField.
You can access items like this prices__0, prices__1, ... (See index transforms)
For instance if you want to order by prices according to today's week day:
from datetime import date
weekday = date.today().weekday()
results = Products.objects.all().order_by('prices__{}'.format(weekday))
You can have another model:
class WeekPrice(...):
#The day field can be a choice field
day = models.CharField(....)
amount = models.DecimalField(..)
class Product(...):
weekly_prices = models.ManyToManyField(..)

How to create specific django-model field, contains a date and unique number per day?

I create a internet-shop on django and have the following problem.
How to create a django model-field for order`s number, contains a date and unique number per day?
This option is described in the assignment and others will not suit me.
UPD:
order number should look like this: yyyymmdd + unique order`s num per day. The next day, this num will start from the beginning.
As a result, I made like this. Maybe someone will come in handy.
from django.db import models
from django.utils.timezone import datetime
def get_num(date=datetime.now()):
date = date.strftime('%Y%m%d')
if Order.objects.all().last():
last_order = Order.objects.all().last()
if last_order.number[0:8] == date:
num = int(last_order.number[8::]) + 1
else:
num = 1
else:
return f'{date}1'
return(f'{date}{num}')
class Order(models.Model):
number = models.CharField(max_length=12, default=get_num, verbose_name='номер заказа')
...

Subtract django.db.models.DateField from python's datetime.date to get age

In django, I want to get the age (in days) of an instance of a class. I tried doing that by subtracting its creation date field from today, but it does not seem to work properly. date.today() works fine, but DateField is giving me trouble. I looked at its source code and the django docs online for my version but I'm not sure how to manipulate it to perform the subtraction.
import datetime.date
from django.db import models
class MyItem(models.Model):
item_name = models.CharField(max_length = 30)
creation_date = models.DateField()
def age(self):
return date.today() - creation_date
my_first_item = MyItem(item_name = 'First', creation_date = '2005-11-01')
print my_first_item.age.days
Any input would be greatly appreciated!
Your problem is that you are trying to use a field instance outside of a model to represent a value.
models.DateField is a class which represents a database field with a type of "date". I suspect that you are looking to do one of the following:
Just do straight date math
Work with a value returned by a model
In the case of 1, you don't want to use Django's models at all. All you need and want is python's date and time handling classes. For your specific example all you need to use is a pair of date objects and you will end up with a timedelta object.
To do what you were trying to do in your example with the python standard classes, see the example below:
from datetime import date
birthday = date(year=2005, month=11, day=1)
today = date.today()
age = today - birthday
print age.days()
Here we instantiate a date with the birthdate values, we get a date with today's values, subtract them to get a timedelta, and finally print the number of days between the two dates.
In the case of 2, let's look at an example model:
class Person(models.Model):
name = models.CharField(max_length=100)
birthday = models.DateField()
Here we have a model where we've used models.CharField and models.DateField to describe a table in the database which contains a "varchar" column and a "date" column. When we fetch instances of this model using the ORM, Django handles converting whatever value the database returns to a native datatype. Now let's look at some code that figures out the age of an instance of a person:
from datetime import date
from myapp.models import Person
person = Person.objects.get(id=1)
age = date.today() - person.birthday
print age.days
Here you can see that we fetch an instance of the person model from the database and then we subtract their birthday from today. We're able to do this here, because when we access "person.birthday" Django is transforming whatever value the database returned into a python date object. This is the same type as the date object returned by "date.today()" so the "-" operator makes sense. The result of the subtraction operation is a timedelta object.