'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