Django Small Project - Workout Tracker (Pt 1)
February 02, 2021
Table of Contents for Project
Intro
As I’ve mentioned previously, I generally only work on my side projects for about an hour at a time. So I basically want to show what that hour might look like for me if I was build a small Django app from scratch. The main caveat here being that I am already comfortable with Django so I can move pretty quickly with it. If you are more comfortable with another framework then you should absolutely use that framework instead. The point is to maximize your productivity if you are short on time.
So for this project I am going to create a simple workout tracker. This project scratches a small itch I’ve had. Basically I just want to track my progress on some strength exercises I’ve been doing. Yes, I am aware that there are many apps that will do this but I like being in control of my data and I really just want something dead-simple that I can log in and look at at a glance.
Goals For This Session
- Scaffold the project
- User registration
- User login
- User logout
I always like to have an idea of what I want to accomplish during a working session. Ideally, these would be typed or written out somewhere but usually I just have a rough idea of what I want to accomplish in my head prior to sitting down to work.
I will be using sqlite for this project, but you could use whatever backend you’d like. For small projects sqlite is fine. It is a hard question to answer, but if you somehow anticipate that your project will grow, then configure your project for postgres.
These two items are things I think I can get done in an hour. Generally speaking, I usually overshoot this list. I’ll probably hold off on handling password management related tasks until later since they are a little more complex. I’ll also focus on just getting the views working and worry about styling later.
Scaffold The Project
- Create a directory for the project and cd into it
mkdir workout_track
cd workout_track
- Create and activate a virtual environment for the project:
virtualenv -p python3 venv
source venv/bin/activate
- Install Django (v3.1.6 for this post)
pip install django
- Use
django-admin
to create a project and cd into the project directory
django-admin startproject workout_track_project
cd workout_track_project
- Use
django-admin
to create an application in the project
django-admin startapp tracker
- Add the
tracker
app to theINSTALLED_APPS
listsettings.py
# workout_track/workout_track_project/settings.py
...
INSTALLED_APPS = [
'tracker',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...
- Run
makemigrations
andmigrate
(the former command might not have any output but I tend to just run it anyways)
python manage.py makemigrations
python manage.py migrate
- Start the server
python manage.py runserver
- Verify your see the default Django splash screen at
http://127.0.0.1:8000
User Management - Login
Once users are able to signup, they also need to be able to login.
- Create the HTML templates for the views
# from the tracker app directory
mkdir -p templates/registration/
touch templates/registration/login.html
- Create a
urls.py
file for thetracker
app
# from the tracker app directory
touch urls.py
- Update the
urls.py
file for thetracker
app created in step 2 with an anapp_name
and url mapping to Django’s built-inLoginView
# workout_track/workout_track_project/tracker/urls.py
from django.urls import path
from django.contrib.auth.views import LoginView
app_name = "tracker"
urlpatterns = [
path("login", LoginView.as_view(), name="login")
]
- Update the project
urls.py
to include the track app’surls.py
# workout_track/workout_track_project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('tracker/', include('tracker.urls')),
path('admin/', admin.site.urls),
]
- Visit
http://127.0.0.1:8000/tracker/login
and confirm you are shown a blank page - Update
tracker/templates/registration/login.html
to include the login form
<form method="POST">
{% csrf_token %} {{form.as_p }}
<input type="submit" value="Login" />
</form>
- Refresh the page at
http://127.0.0.1:8000/tracker/login
and confirm you are shown the form. You can try to log in with a random username and password, but we don’t have any users yet so you should be shown an error.
User Management - Logout
Let’s go ahead and add a logout view. Again, we’ll use a view that Django provides for us out of the box.
- Update your
tracker/urls.py
to include a path to theLogoutView
.
# workout_track/workout_track_project/tracker/urls.py
from django.urls import path
from django.contrib.auth.views import LoginView, LogoutView
from tracker.views import HomeView, UserSignupView
app_name = "tracker"
urlpatterns = [
path('login', LoginView.as_view(), name="login"),
path('logout', LogoutView.as_view(), name="logout"),
]
User Management - Registration
So now we will add a registration view and simple home page view that users are reidrected to once they’re registered. We’ll add an authentication check to the home page view template for debugging purposes right now.
- Create HTML files for the home page and the signup page
touch templates/registration/signup.html
touch templates/tracker/home.html
- Create the
HomeView
intracker/views.py
# workout_track/workout_track_project/tracker/views.py
from django.views.generic.base import TemplateView
class HomeView(TemplateView):
template_name = 'tracker/home.html'
- Add a path in
tracker/urls.py
for theHomeView
# workout_track/workout_track_project/tracker/urls.py
from django.urls import path
from django.contrib.auth.views import LoginView
from tracker.views import HomeView
app_name = "tracker"
urlpatterns = [
path('', HomeView.as_view(), name="home"),
path('login', LoginView.as_view(), name="login"),
path('logout', LogoutView.as_view(), name="logout"),
]
- Update
tracker/templates/tracker/home.html
to include an authentication check and basic header
<h1>Tracker Home Page</h1>
{% if user.is_authenticated %} Hello, {{user.username}}! {% else %} Please
<a href="{% url 'tracker:login' %}">Login</a> {% endif %}
- Verify that the page is displayed at
http://127.0.0.1:8000/tracker/
- Create a view for the signup page using Django’s built-in
UserCreationForm
intracker/views.py
# workout_track/workout_track_project/tracker/views.py
from django.contrib.auth.forms import UserCreationForm
from django.views.generic.edit import FormView
from django.views.generic.base import TemplateView
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.urls import reverse_lazy
class HomeView(TemplateView):
template_name = 'tracker/home.html'
class UserSignupView(FormView):
model = User
form_class = UserCreationForm
success_url = reverse_lazy('tracker:home')
template_name = 'registration/signup.html'
def form_valid(self, form):
user = form.save()
login(self.request, user)
return super().form_valid(form)
- Map the new
UserSignupView
to a path intracker/urls.py
# workout_track/workout_track_project/tracker/urls.py
from django.urls import path
from django.contrib.auth.views import LoginView
from tracker.views import HomeView, UserSignupView
app_name = "tracker"
urlpatterns = [
path('', HomeView.as_view(), name="home"),
path('login', LoginView.as_view(), name="login"),
path('logout', LogoutView.as_view(), name="logout"),
path('signup', UserSignupView.as_view(), name="signup")
]
- Update
tracker/templates/tracker/signup.html
to include the form instance provided by Django
<form method="POST">
{% csrf_token %} {{form.as_p}}
<input type="submit" value="Signup" />
</form>
- Test out the new signup form by creating a user:
joe:test123456789
athttp://127.0.0.1:8001/tracker/signup
. Once you click “Signup” with a valid username and password you should be redirected to the home page view and see the username you entered displayed, “Hello, joe!” (if you used the credentials above).
Update Redirect Urls
Everything is mostly working at this point but we’ll need to specify where we want Django to redirect the users on login and logout.
- Update your project’s
settings.py
to include the following namespaced urls
# workout_track/workout_track_project/settings.py
...
LOGIN_URL = 'tracker:login'
LOGOUT_REDIRECT_URL = 'tracker:login'
LOGIN_REDIRECT_URL = 'tracker:home'
...
Testing
So now we have user registration, login, and logout. Let’s test everything out.
- Visit
http://127.0.0.1:8001/tracker/logout
in your browser to ensure you are logged out. - Create a new user at
http://127.0.0.1:8001/tracker/signup
and ensure you are taking to the home page with your username displayed - Visit
http://127.0.0.1:8001/tracker/logout
again - Visit
http://127.0.0.1:8001/tracker/login
and login with the user credentials you created in step 1 and ensure you are taken to the home page and the username is displayed.
Wrapping Up
That is pretty much it for now. If you are comfortable with Django than this should take less than an hour for sure. It is totally fine if it took more than an hour or each part took an hour! Part of this is just learning how to use the web framework, and you might not be super familiar with it yet.
In part 2 we will go over adding the core functionality to our workout tracker. Including models, views, and templates for tracking workouts.