i'm working on a dashboard project (django + charts.js) that currently looks like this:
currently, all of the charts are based on all the data in the database (approx 1.5 mil lines). however, i'd like these charts to be responsive to the dates indicated in the start date/end date HTML widget - e.g. show payment methods, taxi orders by the hour/day of week according to the start/end dates indicated.
my date_input
method gets the start and end dates from the frontend, and queries my MySQL database according to the dates selected. these queries are then rendered to the context
variable of date_input
- however, i'd like the context
variable in date_input
to be available to all methods (each chart is rendered by a different method, based on the JsonResponse returned to different endpoints).
i've tried making context
available as a global variable by defining it outside date_input
as queryset = date_input(request)
- NameError: name 'request' is not defined
. i've looked into context processors
, but that seems to be an option only if i didn't have a request (e.g. start/end date input from the frontend). i'm rather confused and would appreciate some help.
here's my views.py code:
def date_input(request):
if request.method == "POST":
context = {}
start_date = request.POST.get("start_date", None) # type unicode
end_date = request.POST.get("end_date", None)
form = DateForm(request.POST or None)
if form.is_valid():
start_date = form.cleaned_data['start_date']
end_date = form.cleaned_data['end_date']
context['start_date'] = Order.objects.filter(member_created_time__gte=(start_date)) # this works
context['end_date'] = Order.objects.filter(order_ended_time__lte=(end_date))
print("weeeeeee!")
print(context['start_date']) # type queryset
print("----")
print(context['end_date'])
return render(request, 'date_input.html', context) # return JSON response to frontend
# return JsonResponse({
# "context": float(context),
# })
else:
form = DateForm()
# print("form is not valid")
# return JsonResponse({
# "form": float(form),
# })
return render(request, 'date_input.html', {
"form": form
})
dow_queryset = Member.objects.order_by('member_created_time').values_list('member_created_time', flat=True)
hkt = pytz.timezone('Asia/Shanghai')
dt_obj = [hkt.localize(datetime.datetime.fromtimestamp(x)) for x in dow_queryset]
def charts(request): # pie chart for payment type
queryset = Order.objects.order_by('payment').values(
'payment').annotate(payment_type=Count('payment'))
default = list(queryset.values_list('payment_type', flat=True))
labels = list(queryset.values_list('payment', flat=True))
return JsonResponse({
'labels': labels, # payment methods
'default': default, # payment methods
})
def hourly(request): # bar chart to show taxi orders by hour of day
hour_count = OrderedDict()
hour_count['midnight'] = 0
hour_count['early_morning'] = 0
hour_count['morning'] = 0
hour_count['afternoon'] = 0
hour_count['night'] = 0
for obj in dt_obj:
if obj.hour == 0:
hour_count['midnight'] += 1
elif obj.hour < 6:
hour_count['early_morning'] += 1
elif obj.hour < 12:
hour_count['morning'] += 1
elif obj.hour < 19:
hour_count['afternoon'] += 1
else:
hour_count['night'] += 1
return JsonResponse({
'labels_hour': list(hour_count.keys()),
'data_hour': list(hour_count.values()),
})
def dow(request): # bar chart to show no. of rides for each day fo the week
weekday_count = OrderedDict()
weekday_count['monday'] = 0
weekday_count['tuesday'] = 0
weekday_count['wednesday'] = 0
weekday_count['thursday'] = 0
weekday_count['friday'] = 0
weekday_count['saturday'] = 0
weekday_count['sunday'] = 0
for obj in dt_obj:
if obj.weekday() == 0:
weekday_count['monday'] += 1
elif obj.weekday() == 1:
weekday_count['tuesday'] += 1
elif obj.weekday() == 2:
weekday_count['wednesday'] += 1
elif obj.weekday() == 3:
weekday_count['thursday'] += 1
elif obj.weekday() == 4:
weekday_count['friday'] += 1
elif obj.weekday() == 5:
weekday_count['saturday'] += 1
elif obj.weekday() == 6:
weekday_count['sunday'] += 1
return JsonResponse({
'labels_day' : list(weekday_count.keys()),
'data_day': list(weekday_count.values()),
})
date_input.html (i have html files, titled charts.html
, day.html
, and hour.html
for each chart respectively. the code is all quite similar in that they all use AJAX requests)
{% load static %}
{% block content %}
<div class="date">
<br>
<h3>Select to view distance and orders by timeframe</h3>
<form name="date-input" method="POST" action="/date-input/">
<label for="start">Start date:</label>
<input type="date" id="start" name="start_date" value="2019-01-01" min="2019-01-01" max="2019-06-30">
<label for="end">End date:</label>
<input type="date" id="end" name="end_date" value="2019-01-01" min="2019-01-01" max="2019-07-01">
<br>
<br>
</form>
</div>
{% endblock content %}
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script>
var start_date = Date.parse($("#start").val())/1000; // const can't be re-assigned or redeclared. Date() to convert datetime into epoch time
var end_date = Date.parse($("#end").val())/1000; // divide by 1000 to get 10 digits (compatible with values in DB)
function ajaxRequest (){
var start_date = Date.parse($("#start").val())/1000;
var end_date = Date.parse($("#end").val())/1000;
$.ajax({ // initialize an AJAX request
type: "POST",
url: '/date-input/', // calls data from /date-input/ endpoint
data: {
'start_date': start_date, // add the order id to the POST parameters
'end_date': end_date,
'csrfmiddlewaretoken': "{{csrf_token}}",
},
success: function (data) { // `data` is from `homepage` view function
console.log("this block of code isn't useless!!")
console.log(data.start_date)
console.log(data.end_date)
},
error: function (data, xhr, status, error) {
console.log("yikes")
}
});
}
$("#start, #end").change(function() { // calling select id
start_date = Date.parse($("#start").val())/1000;
end_date = Date.parse($("#end").val())/1000; // get the selected subject ID from the HTML dropdown list
if (start_date < end_date) {
ajaxRequest();
}
});
</script>