23
loading...
This website collects cookies to deliver better user experience
mkdir django_charts_books_project && cd django_charts_books_project
virtualenv env
pipenv
or any other pyenv
command line tools.source env/bin/activate
pip install django #1
django-admin startproject books_project . #2
python manage.py startapp books #3
books_project/settings.py
file and ensure you add 'books', to the list of INSTALLED_APPS
section. from django.db import models
# Create your models here.
class Book(models.Model):
title=models.CharField(max_length=250)
author=models.CharField(max_length=250)
price=models.FloatField(default=0)
def __str__(self) -> str:
return str(self.title)
class Purchase(models.Model):
PAYMENT_METHODS=[
('Mpesa','Mpesa'),
('Card','Card'),
('Cash','Cash')
]
customer=models.CharField(max_length=250)
book=models.ForeignKey('Book',on_delete=models.CASCADE)
payment_method=models.CharField(max_length=6, choices=PAYMENT_METHODS)
time_created=models.DateTimeField(auto_now_add=True)
is_successful=models.BooleanField(default=True)
def __str__(self) -> str:
return str(self.book)
admin.py
python manage.py makemigrations #sync the db
python manage.py migrate #apply migrations
db.sqlite3
database that ships with Django. import random
from datetime import date, datetime, time,timedelta
import pytz
from django.core.management.base import BaseCommand
from books.models import Book, Purchase
from random import randint
#will use to generate a 3 digit number to act as price of a book
def random_with_N_digits(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
class Command(BaseCommand):
help='Populates the db wit random generated data'
def add_arguments(self, parser):
parser.add_argument('--amount',type=int, help='The number of purchases that should be created.')
def handle(self, *args, **kwargs):
books= [
'Sapiens',
'Man’s search for meaning',
'The War of Art',
'How to win friends and influence people',
'Meditation',
'Shoe Dog',
'The Predatory Female',
'The Rationale Male - Religion',
'The lean startup',
'In Pursuit of Purpose',
'The 4 -Hour work week',
'7 habits of Highly Effective Men',
'As a Man Thinketh',
'The Intelligent Investor',
'How Not To Die',
'The Manipulated Man',
'The Lessons of History',
'Why we eat too much',
'The Art of War',
'Can’t hurt me',
'Made to Stick',
'Atomic Habits',
'Homo Deus',
'12 Rules for Life',
'The Power of Habit',
'Good to Great',
'Why we sleep',
'The Emperor of All Maladies',
'Why Nations Fail',
'Blood and Oil'
]
authors=[
'Yuval Harari',
'Viktor Frankl',
'Steven Pressfield',
'Dale Carnegie',
'Marcus Aurelius',
'Phil Knight',
'Lawrence Shannon',
'Rollo Tomassi',
'Eric Ries',
'Myles Munroe',
'Tim Ferris',
'Stephen R Covey',
'James Allen',
'Benjamin Graham',
'Dr. Michael Greger',
'Esther Vilar',
'Will & Ariel Durant',
'Dr. Andrew Jenkinson',
'Sun Tzu',
'David Goggins',
'Chip Heath & Dan Heath',
'James Clear',
'Noah Harari',
'Jordan B Peterson',
'Charles Duhigg',
'Jim Collins',
'Matthew Walker',
'Siddhartha Mukherjee',
'Daron Acemoglu & James Robinson',
'Bradley Hope & Justin Scheck',
]
prices=[]
customers=['Nick','Kibet','Vin','Lyn','Mary','John','Dan','Doro']
for i in range(31):
price=random_with_N_digits(3)
prices.append(price)
book_list=[]
for book, author, price in zip(books, authors, prices):
x=Book.objects.get_or_create(
title=book,
author=author,
price=price
)
book_list.append(x)
print(book_list)
amount=kwargs['amount'] if kwargs['amount'] else 150
for i in range(0, amount):
dt=pytz.utc.localize(datetime.now() - timedelta(days=random.randint(0, 1200)))
purchase = Purchase.objects.create(
customer=random.choice(customers),
book=random.choice(book_list)[0],
payment_method=random.choice(Purchase.PAYMENT_METHODS)[0],
is_successful=True if random.randint(1,2)==1 else False
)
purchase.time_created=dt
print(purchase)
purchase.save()
self.stdout.write(
self.style.SUCCESS(
'Done populating the database'
)
)
env
is activated:python manage.py populate_db
python manage.py createsuperuser
then head over to (http://localhost:8000/admin/) and check. utils.py
. Inside it paste the follwing code:months = [
'January', 'February', 'March', 'April',
'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December'
]
colorPalette = ['#00ccff ', '#ff33cc', '#ff0066', '#00ffcc', '#290066', '#ff3300', '#ffff00']
colorPrimary, colorSuccess, colorDanger = '#79aec8', colorPalette[0], colorPalette[5]
def get_year_dict():
year_dict = dict()
for month in months:
year_dict[month] = 0
return year_dict
def generate_color_palette(amount):
palette = []
i = 0
while i < len(colorPalette) and len(palette) < amount:
palette.append(colorPalette[i])
i += 1
if i == len(colorPalette) and len(palette) < amount:
i = 0
return palette
views.py
and add the code below:from django.shortcuts import render
from django.db.models import Count,F,Sum,Avg
from django.db.models.functions import ExtractYear,ExtractMonth
from django.http import JsonResponse
from .models import Book, Purchase
from .utils import (
months,colorDanger,
colorPrimary,colorSuccess,
generate_color_palette,get_year_dict)
# Create your views here.
def display_charts(request):
return render(request, 'charts.html', {})
def filter_options(request):
merged_purchases=Purchase.objects.annotate(
year=ExtractYear(
'time_created'
)).values(
'year'
).order_by(
'-year'
).distinct()
options= [purchase['year'] for purchase in merged_purchases]
return JsonResponse(data={
'options':options
})
def get_annual_sales(request, year):
purchases=Purchase.objects.filter(time_created__year=year)
merged_purchases=purchases.annotate(
price=F('book__price')
).annotate(month=ExtractMonth('time_created')).values(
'month'
).annotate(
average=Sum(
'book__price'
)
).values(
'month',
'average'
).order_by('month')
sales_dict=get_year_dict()
for merge in merged_purchases:
sales_dict[months[merge['month']-1]]=round(merge['average'], 2)
return JsonResponse({
'title':f'Sales in {year}',
'data':{
'labels':list(sales_dict.keys()),
'datasets':[{
'label':'Amount (KSHS)',
'backgroundColor':generate_color_palette(7),
'borderColor':generate_color_palette(5),
'data':list(sales_dict.values())
}]
}
})
from django.urls import path, include
from .import views
urlpatterns = [
path('', views.display_charts, name='index'),
path('filters', views.filter_options,name='filter_options'),
path('annual/<int:year>/sales', views.get_annual_sales, name='annual_chart'),
]
settings.py
with the following code inside the DIRS
array of the TEMPLATES SECTION
:'DIRS': [os.path.join(BASE_DIR, 'templates')],
charts.html
.python manage.py runserver