0% found this document useful (0 votes)
25 views10 pages

Nutrient Counter Tutorial

This document outlines the steps to create a Django project named 'n_counter' for tracking nutrient consumption. It includes instructions for setting up a virtual environment, creating models for food items and consumption, and implementing views and templates for displaying and managing food data. Additionally, it covers enhancements such as adding a progress bar for calorie tracking, creating charts for nutrient breakdown, and implementing a deletion feature for consumed food items.

Uploaded by

kenseykhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views10 pages

Nutrient Counter Tutorial

This document outlines the steps to create a Django project named 'n_counter' for tracking nutrient consumption. It includes instructions for setting up a virtual environment, creating models for food items and consumption, and implementing views and templates for displaying and managing food data. Additionally, it covers enhancements such as adding a progress bar for calorie tracking, creating charts for nutrient breakdown, and implementing a deletion feature for consumed food items.

Uploaded by

kenseykhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

## Create venv for nutrient_counter project and activate it

py -m venv new
new\Scripts\activate.bat

## install Django

pip install django

## create project "n_counter"

django-admin startproject n_counter

## create app "app"

py manage.py startapp app

## add app in INSTALLED_APPS in settings.py

## create model for Food items in models.py

from django.db import models

class Food(models.Model):

name = models.CharField(max_length=250)
carbs= models.FloatField(default=0)
proteins = models.FloatField(default=0)
fats= models.FloatField(default=0)
calories = models.IntegerField(default=0)

## migrate model

py manage.py makemigrations
py manage.py migrate

## register model in admin.py

from django.contrib import admin


from .models import Food

admin.site.register(Food)

## Create superuser for project

py manage.py createsuperuser

## Add __str__ for Food model to be displayed (update models.py)

from django.db import models

class Food(models.Model):

def __str__(self):
return self.name

name = models.CharField(max_length=250)
carbs= models.FloatField(default=0)
proteins = models.FloatField(default=0)
fats= models.FloatField(default=0)
calories = models.IntegerField(default=0)

##Create view for display food items in views.py

from django.shortcuts import render


from .models import Food

def index(request):
foods = Food.objects.all()
return render(request, 'app/index.html', {'foods':foods})

##Create templates folder with internal 'app' in app

##Create index.html in templates/app

<html>
<head>

</head>
<body>
{% for food in foods %}
{{food.name}}<br>
{% endfor %}

</body>
</html>

##register path for view in urls.py

from django.contrib import admin


from django.urls import path
from app import views

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name="index")
]

##add select box of food from form (update index.html)

<html>
<head>

</head>
<body>
<form action="">
{% csrf_token %}
<select name="" food="">
{%for food in foods%}
<option value="{{food.name}}">{{food.name}}</option>
{% endfor %}
</select>
</form>
</body>
</html>
## Add food consumption list for users (import default User model). Create model
'Consume' in models.py

from django.contrib.auth.models import User

class Consume(models.Model):

food_consumed = models.ForeignKey(Food, on_delete=models.CASCADE)


user = models.ForeignKey(User, on_delete=models.CASCADE)

## Register model in admin.py

from .models import Food, Consume

admin.site.register(Food)
admin.site.register(Consume)

## Start migrations

py manage.py makemigrations
py manage.py migrate

py manage.py runserver

## Check on the server create consume

##add the functionality of selecting food item for each user separately (create
right association)

##update index.html

<html>
<head>

</head>
<body>
<form method="POST">
{% csrf_token %}
<select name="food_consumed" id="food_consumed">
{% for food in foods %}
<option value="{{food.name}}">{{food.name}}</option>
{% endfor %}
</select>
<button type="submit">Add

</button>

</form>
</body>
</html>

##In views.py update def index according to the POST method and added name and id
in html

from django.shortcuts import render


from .models import Food, Consume
def index(request):

if request.method =="POST":
food_consumed = request.POST['food_consumed']
consume = Food.objects.get(name=food_consumed)
user = request.user
consume = Consume(user=user, food_consumed=consume)
consume.save()
foods = Food.objects.all()

else:
foods = Food.objects.all()

return render(request, 'app/index.html', {'foods':foods})

##Show the listing of consumed food. Update the views.py

...
if request.method =="POST":
food_consumed = request.POST['food_consumed']
consume = Food.objects.get(name=food_consumed)
user = request.user
consume = Consume(user=user, food_consumed=consume)
consume.save()
foods = Food.objects.all()

else:
foods = Food.objects.all()
consumed_food=Consume.objects.filter(user=request.user)

return render(request, 'app/index.html', {'foods':foods,


'consumed_food':consumed_food})

##Update index.html with after <form> part

...
</form>

{% for c in consumed_food %}
{{c.food_consumed.name}} --> {{c.food_consumed.carbs}} -->
{{c.food_consumed.calories}} </br>
{% endfor %}
...

##Add bootstrap tp the html templates (in head tag)

<head>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N"
crossorigin="anonymous">

</head>

##Refine the index.html <form> part


...
<div class="container">
<div class="row">
<div class="col-md-12">
<form method="POST">
<div class="form-group row">
{% csrf_token %}
<label class="col-md-2">
<b>Select Food To Add </b>

</label>
<select class="col-md-6 form-control"
name="food_consumed" id="food_consumed">
{% for food in foods %}
<option
value="{{food.name}}">{{food.name}}</option>
{% endfor %}
</select>
<button class="btn btn-success"
type="submit">Add</button>
</div>
</form>
</div>
</div>
</div>
...

##Create a table of consumed nutrientsinstead of previous listing with '{% for c in


consumed_food %}' loop

...

<div class="row">
<div class="col-md-7">
<div >
<h4> Today's Consumption</h4>
</div>

<table id="table" class="table table-striped table-primary">


<tr class="bg-primary text-white">
<th>Food item</th>
<th>Carbs(gm)</th>
<th>Protein(gm)</th>
<th>Fats(gm)</th>
<th>Calories(Kcal)</th>

</tr>
{% for c in consumed_food %}
<tr>
<td>{{c.food_consumed.name}}</td>
<td>{{c.food_consumed.carbs}}</td>
<td>{{c.food_consumed.proteins}}</td>
<td>{{c.food_consumed.fats}}</td>
<td>{{c.food_consumed.calories}}</td>
</tr>

{% endfor %}
</table>
</div>
</div>
...

## Add the calculations of total numbers of nutrients. Add <script> after </body>

<script>
var table = document.getElementById("table");
var carbs = 0, proteins=0, fats=0, calories=0;
for(var i=1; i<table.rows.length-1;i++){
console.log(table.rows[i].cells[1].innerHTML);
carbs += parseFloat(table.rows[i].cells[1].innerHTML);
proteins += parseFloat(table.rows[i].cells[2].innerHTML);
fats += parseFloat(table.rows[i].cells[3].innerHTML);
calories += parseFloat(table.rows[i].cells[4].innerHTML);
}
</script>

## Add new row for Total counts

...
{% endfor %}

<tr>
<td id="name"><b>Total</b></td>
<td id="totalCarbs"><b></b></td>
<td id="totalProteins"><b></b></td>
<td id="totalFats"><b></b></td>
<td id="totalCalories"><b></b></td>

</tr>
</table>
...

## Add update for <script>

<script>
var table = document.getElementById("table");
var carbs = 0, proteins=0, fats=0, calories=0;
for(var i=1; i<table.rows.length-1;i++){
console.log(table.rows[i].cells[1].innerHTML);
carbs += parseFloat(table.rows[i].cells[1].innerHTML);
carbs = Math.round(carbs);
proteins += parseFloat(table.rows[i].cells[2].innerHTML);
fats += parseFloat(table.rows[i].cells[3].innerHTML);
calories += parseFloat(table.rows[i].cells[4].innerHTML);
}
console.log(carbs);
document.getElementById("totalCarbs").innerHTML = '<b>' + carbs +
'(gm)</b>';
document.getElementById("totalProteins").innerHTML = proteins;
document.getElementById("totalFats").innerHTML = fats;
document.getElementById("totalCalories").innerHTML = '<b>' + calories +
'(kcal)</b>';
</script>

##Add progress bar for calories. in index.html in container div add boostrap
'progress-bar'

...
<div class="container">
<br><br><br>

<h4>Calorie Goal</h4>
<br>
<div class="row">
<div class="col-md-9 offset-1">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width:
0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="0"></div>
</div>
</div>
</div>
<br><br>

<div class="row">

...

##Update the <script> with var for % of calories

...
document.getElementById("totalFats").innerHTML = fats;
document.getElementById("totalCalories").innerHTML = '<b>' + calories +
'(kcal)</b>';

var calPer = (calories/2000)*100;


document.getElementsByClassName("progress-bar")[0].setAttribute("style",
"width:"+calPer+"%");

</script>
...

##Add nav bar for the index.html after "container"

...
<div class="container">
<div class="row">
<div class="col-md-12">
<nav class="navbar navbar-dark bg-primary">
<span class="navbar-brand">Calorie Tracker</span>
</nav>
</div>
</div>

<br><br><br>
...

##In index.html add the headers for Chart.js charts


...
</table>
</div>

<div class="col-md-5" offset-1>


<div class="">
<h4>Today's breakdown</h4>
</div>

<div class="card-header text-white bg-primary">


<h4>Macronutrients breakdown</h4>
</div>

<div class="col-md-12">

</div>
</div>
</div>
</div>
{% for c in consumed_food %}
...

##Go to chart.js official site, get the CDN and copy the HTML add-on. Insert the
copied HTML to the index.html

...
<head>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N"
crossorigin="anonymous">
<script
src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
</head>
...

## in index.html setup the column after Macronutrient breakdown

...
<h4>Macronutrients breakdown</h4>
</div>

<div class="col-md-12">
<canvas id="myChart" width="400" height="400"></canvas>

</div>
...

##In <script> part of index.html add the definition of doughnut chart

...
document.getElementsByClassName("progress-bar")[0].setAttribute("style",
"width:"+calPer+"%");

var total = carbs + proteins +fats;


var carbsP= Math.round((carbs/total)*100);
var proteinsP= Math.round((proteins/total)*100);
var fatsP= Math.round((fats/total)*100);

var ctx = document.getElementById('myChart').getContext('2d');


var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Carbs '+carbsP+'%', 'Proteins '+proteinsP+'%', 'Fats
'+fatsP+'%'],
datasets: [{
data: [carbsP, proteinsP, fatsP],
backgroundColor: [
'rgba(255, 99, 132, 0.6)',
'rgba(255, 255, 100, 0.6)',
'rgba(255, 79, 12, 0.6)',
],
borderColor: [
'rgba(255, 99, 132, 0.9)',
'rgba(255, 255, 100, 0.9)',
'rgba(255, 79, 12, 0.9)',
],
borderWidth: 1
}]
}
});

</script>
...

##Add the deletion functionality to the list of food items. In views.py add def
delete_consume() and import 'redirect' from shortcuts

def delete_consume(request, id):


consumed_food = Consume.objects.get(id=id)
if request.method == 'POST':
consumed_food.delete()
return redirect('/')
return render(request, 'app/delete.html')

##Create confirmation form template delete.html

<!DOCTYPE html>
<html lang="en">

<head>
<title>Document</title>
</head>

<body>
<form method="POST">
{% csrf_token %}
Are you sure you want to delete the item?
<input type="submit">
</form>
</body>
</html>
##Setup urls.py with new view

from django.contrib import admin


from django.urls import path
from app import views

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name="index"),
path('delete/<int:id>/', views.delete_consume, name="delete"),

## Add the remove character in index.html for each item listed

...
<table id="table" class="table table-striped table-primary">
<tr class="bg-primary text-white">
<th>Food item</th>
<th>Carbs(gm)</th>
<th>Protein(gm)</th>
<th>Fats(gm)</th>
<th>Calories(Kcal)</th>
<th>Remove item</th>

</tr>
{% for c in consumed_food %}
<tr>
<td>{{c.food_consumed.name}}</td>
<td>{{c.food_consumed.carbs}}</td>
<td>{{c.food_consumed.proteins}}</td>
<td>{{c.food_consumed.fats}}</td>
<td>{{c.food_consumed.calories}}</td>
<td><a class="btn btn-danger" href="{% url
'delete' c.id %}">Remove</td>
</tr>

{% endfor %}
...

##Change the 'Remove' button name to 'X'

You might also like