0% found this document useful (0 votes)
5 views

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)
5 views

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
You are on page 1/ 10

## 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