'Django Chart data and labels
I'm currently making a dashboard that shows data for staff. I have made a function to get chart data and labels, so far, I've managed to do the labels.. but I can't seem to get the count for the amount of occurrences for each of the dates. I need the output for get_chart_data to be a list or tuple like this: 20/01/2022: 1,
That means that on that day I only had 1 object added to the database for example.
The code I have tried so far have failed, or give me the count up to a certain date but nothing correct. The important part is that the date range is dynamic.
Views.py
@login_required(login_url='/accounts/login/')
def get_chart_data(request, model, data_range):
end_date = dt.localdate()
print(end_date)
start_date = dt.localdate()- timedelta(days=data_range)
print(start_date)
db_objects = model.filter(transaction_date__lte=end_date, transaction_date__gt=start_date).\
values('transaction_date').\
annotate(count=Count('purchase_id'))
print(db_objects)
amount_objects = list(db_objects)
print(amount_objects)
dates = [x.get('transaction_date') for x in amount_objects]
print(dates)
for d in (end_date - start_date for x in range(0,data_range)):
if d not in dates:
amount_objects.append({'createdate': d, 'count': 0})
data = amount_objects
return data
@login_required(login_url='/accounts/login/')
def get_label_data(request, model, data_range):
label = []
end_date = dt.localdate()
start_date = dt.localdate()- timedelta(days=data_range - 1)
delta = start_date - end_date # returns timedelta
for i in range(data_range):
day = start_date + timedelta(days=i)
day_str = day.strftime('%A')
label.append(day_str)
return label
Output:
2022-01-20
2022-01-13
C:\Users\akram\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\__init__.py:1358: RuntimeWarning: DateTimeField purchase.transaction_date received a naive datetime (2022-01-13 00:00:00) while time zone support is active.
warnings.warn("DateTimeField %s.%s received a naive datetime "
C:\Users\akram\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\__init__.py:1358: RuntimeWarning: DateTimeField purchase.transaction_date received a naive datetime (2022-01-20 00:00:00) while time zone support is active.
warnings.warn("DateTimeField %s.%s received a naive datetime "
<QuerySet [{'transaction_date': datetime.datetime(2022, 1, 17, 8, 24, 31, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 16, 8, 16, 42, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 16, 8, 14, 7, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 15, 8, 13, 15, tzinfo=<UTC>), 'count': 1}]>
[{'transaction_date': datetime.datetime(2022, 1, 17, 8, 24, 31, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 16, 8, 16, 42, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 16, 8, 14, 7, tzinfo=<UTC>), 'count': 1}, {'transaction_date': datetime.datetime(2022, 1, 15, 8, 13, 15, tzinfo=<UTC>), 'count': 1}]
[datetime.datetime(2022, 1, 17, 8, 24, 31, tzinfo=<UTC>), datetime.datetime(2022, 1, 16, 8, 16, 42, tzinfo=<UTC>), datetime.datetime(2022, 1, 16, 8, 14, 7, tzinfo=<UTC>), datetime.datetime(2022, 1, 15, 8, 13, 15, tzinfo=<UTC>)]
[20/Jan/2022 10:35:30] "GET /pwl-access/view-all-purchases/ HTTP/1.1" 200 29402
in the above output it shows, 1 for each date, but that is incorrect.it's also important to note that the functions has to show 0 if there was no occurences for that date. I'm calling the functions like this:
chart_data = get_chart_data(request, view_all_objects, int(7) )
chart_labels = get_label_data(request, view_all_objects, int(7) )
Any help would be greatly appreciated.
EDIT: I am also looking for the function to work for more then just the same date range..
Solution 1:[1]
very simple and elegant, I've resolved it by using the following functions:
def extract_labels_data_set_from_model_data(data,start_date,end_date):
all_dates = []
graph_data = None
incoming_data = [str(x) for x in data]
while start_date<end_date:
start_date = start_date + datetime.timedelta(days=1)
all_dates.append(start_date.date())
if data:
data = data + [x for x in all_dates if x not in data]
if data:
data = list(sorted(data))
data = dict(Counter(data))
labels = list(data.keys())
data_set = list(data.values())
graph_data = {
"labels":[str(x) for x in labels],
"data_set":[str(x) for x in data_set],
"start_date":str(start_date),
"end_date":str(end_date),
"total_price":str(total_price),
}
extra_dates = [str(x) for x in graph_data ['labels'] if x not in incoming_data]
for index,x in enumerate(graph_data['labels']):
if x in extra_dates:
graph_data['data_set'][index] = 0
print("-> Graph Data",graph_data)
return json.dumps(graph_data)
def get_interval_based_model_data(request=None,start_date=None,end_date=None,model_name=None):
data = None
if request is not None:
start_date = request.GET['start_date']
end_date = request.GET['end_date']
model_name = request.GET['model_name']
try:
start_date = make_aware(datetime.datetime.strptime(start_date, '%Y-%m-%d'))
end_date = make_aware(datetime.datetime.strptime(end_date, '%Y-%m-%d'))
if str(model_name).lower() == 'enquiries'.lower():
data = enq.objects.filter(date_submitted__gte=start_date,date_submitted__lte=end_date).order_by('date_submitted').values('date_submitted')
print("->Records Found = ", data.count())
data = [x['date_submitted'].date() for x in data]
if request is None:
return extract_labels_data_set_from_model_data(data,start_date,end_date)
except Exception as e:
print(e)
pass
return JsonResponse({'graph_data':extract_labels_data_set_from_model_data(data,start_date,end_date)})
In case anyone had any difficulty in doing this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Akram Alkhatar |
