Plot your data in your Django web application with Plotly (Part 2).
Hi Medium readers! I hope the Easter was nice for all of you!
Lets continue our Body Mass Index (BMI) calculator started in the previous article Plot your data in your Django web application with Plotly (Part 1).
Update
In the mentioned article we were creating a project called ‘BMICalculator’, with an application inside called ‘BMIApp’.
Also we created a landing view in the ‘views.py’ file called ‘index()’. In this view we learned how to embed a Plotly plot to display it in an HTML web page:
Check Plot your data in your Django web application with Plotly (Part 1) for any doubts.
As a summary, we have created a project, with a BMI application inside with a landing view that displays a bar plot.
Now we need to finish our BMI calculator. To do that, in this article we’ll:
- Make our BMI calculator work.
- Make the needed calculations to get the BMI index value.
Make our BMI calculator work.
To do this, we need some things:
- Form to introduce data for BMI calculation.
- Add code in the landing view to send data through the POST method request.
BMI form
To create a form for the ‘BMIApp’ I’ll use Django forms.
Django provides a range of tools and libraries to help you build forms to accept input from site visitors, and then process and respond to the input.
So, before to create the form we need to know what we need to calculate a BMI index. What we need is the height and the weight from someone to calculate his/her BMI.
The BMI is defined as the body mass divided by the square of the body height, and is expressed in units of kg/m², resulting from mass in kilograms and height in meters.
Once we know what we need to calculate the BMI, we can easily create a Django form class with two attributes, height and weight, like this:
from django import forms
# BMI form class
class BMIForm(forms.Form):
# Height input
height = forms.FloatField( required = True,
label = "Height (m)",
min_value = 0.30,
max_value = 2.80,
widget = forms.NumberInput(
attrs={ 'id': 'form_height',
'step': "0.01"}))
# Weight input
weight = forms.FloatField( required = True,
label = "Weight (Kg)",
min_value = 2,
max_value = 350,
widget = forms.NumberInput(
attrs={ 'id': 'form_weight',
'step': "0.01"}))
After the Django form creation, we need to import our class form in the ‘views.py’ to be able to initiate a new ‘BMIForm’ instance and send it to the template by adding it into the context template like this:
from .forms import BMIForm
# BMIApp landing view
def index(request):
'''
Landing view for the BMI Calculator.
'''
if request.method == 'GET':
# BMI form
bmi_form: BMIForm = BMIForm()
# Template context date
context: dict = { 'title': 'BMI Calculator',
'bmi_form': bmi_form}
return render(request, 'BMIApp/base.html', context)
Add code in the landing view
Also we need to modify our landing view to display our ‘BMIForm’ like this:
<form class="m-0 p-0 pt-4 pb-4 w-25 text-center bg-success text-white rounded" action="{% url 'BMIApp:index' %}" method="post">
{% csrf_token %}
{% for field in bmi_form %}
<p class="w-100 text-center fs-6 m-0 p-0"><small>{{field.label}}</small></p>
<div class="w-100 text-center m-0 mb-2 p-0 form_field">{{field}}</div>
{% endfor %}
<button class="w-75 m-0 p-1 fs-6 btn btn-sm btn-primary" type="submit">Calculate BMI</button>
</form>
Now, if we visit our landing view in the ‘http://127.0.0.1:8000/’ URL, we should see something similar to the next image (I added some Bootstrap to make it a bit more user friendly):
Calculations to get the BMI
Once we have the form design and everything ready in the template, lets calculate the BMI.
To do that, we’ll create an ‘if’ statement for the POST requests in our ‘index()’ view, and get the weight and the height values from the POST request:
if request.method == 'POST':
bmi_form: BMIForm = BMIForm()
height: str = request.POST['height']
weight: str = request.POST['weight']
Calculate BMI
The BMI formula is the next: BMI = weight / (height*height), so it would be very difficult to calculate the BMI. An option would be:
bmi_result: float = float(weight)/(float(height)*float(height))
Categorize the BMI result
Once we have the BMI value, is important to categorize this value and see in which category it falls.
I created some ‘if’ statements to better explain the BMI categorization, but this could be easily done by a Python dictionary:
# Underweight
if bmi_result < 18.5:
result: str = 'Underweight'
# Healthy Weight
elif (bmi_result >= 18.5) and (bmi_result < 25):
result: str = 'Healthy Weight'
# Overweight
elif (bmi_result >= 25) and (bmi_result < 30):
result: str = 'Overweight'
# Obessity class I
elif (bmi_result >= 30) and (bmi_result < 35):
result: str = 'Obessity class I'
# Obessity class II
elif (bmi_result >= 35) and (bmi_result < 40):
result: str = 'Obessity class II'
# Obessity class III
elif (bmi_result >= 40):
result: str = 'Obessity class III'
Create a barplot with the introduced data and with the result as explained in the Plot your data in your Django web application with Plotly (Part 1) article, and embed it for the HTML web page:
# Create bar plot
bmi_plot: Figure = px.bar(x = ["Height", "Weight", "BMI index"],
y = [float(height), float(weight), bmi_result])
# Embed the plot in a div tag
bar_plot_div: str = plot(bmi_plot, output_type="div")
And sent it to the view:
# Template context date
context: dict = { 'title': 'BMI Calculator',
'bmi_form': bmi_form,
'bmi_plot': bar_plot_div,
'result': result}
Test the view
Execute the ‘BMIApp’ and access to the ‘http://127.0.0.1:8000/’.
And introduce the form data, lets say 1.70m, for the height and 75kg for the weight, and see the result:
Up to here the BMI Calculator! I hope was useful!
Thanks for reading me!
Remember to clap the article if you liked!