Setting Up Django and Building a Poll App: My Last Two Weeks of Work
Ashley Obano
Posted on September 16, 2024
Over the past two weeks, I've been working on setting up Django from scratch and building a simple poll application. This article will walk you through everything I did, starting from installing Python and Django, setting up a virtual environment, creating a new project, and building a functional app called polls.
1. Setting Up Python and Django
To begin, I made sure that Python was installed on my system. If you haven't installed it yet, you can download it from python.org.
Step 1: Install Python and Set Up a Virtual Environment
I wanted to keep my project dependencies isolated, so I used a virtual environment.
# Install virtualenv if you don't have it
pip install virtualenv
# Create a virtual environment
virtualenv myenv
# Activate the environment
# On Windows:
myenv\Scripts\activate
# On macOS/Linux:
source myenv/bin/activate
Step 2: Install Django
Once the environment was activated, I installed Django.
pip install django
I then confirmed the installation by running:
django-admin --version
2. Starting a New Django Project: mysite
Now, it was time to create my Django project. I decided to call it mysite.
django-admin startproject mysite
cd mysite
This created the basic structure for a Django project with settings and configurations.
3. Creating a New Django App: polls
After setting up the project, I created a new app called polls, which would contain all the logic and views for my poll application.
python manage.py startapp polls
I added the new app to INSTALLED_APPS in mysite/settings.py:
INSTALLED_APPS = [
# other installed apps
'polls',
]
4. Defining the Models
I started by defining two models: Question and Choice. A Question has a question text and a publication date, while a Choice has a reference to a Question and stores text along with a vote count.
Here’s the models.py file in the polls app:
# models.py
import datetime
from django.db import models
from django.contrib import admin
from django.utils import timezone
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
@admin.display(
boolean=True,
ordering='pub_date',
description='Published recently?',
)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
5. Creating the Database and Running Migrations
Next, I created the database and applied migrations:
python manage.py migrate
I then created migration files for the polls app:
python manage.py makemigrations polls
python manage.py migrate
6. Writing Views for the Poll App
I wrote several views to handle displaying a list of questions, showing question details, and showing voting results. These views are class-based, using Django’s built-in generic views.
Creating Views for Polls
I then created the views that control how data is displayed to the user. I used Django's generic views to keep things simple.
Here’s the views.py file:
# views.py
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from django.utils import timezone
from .models import Question, Choice
class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'
def get_queryset(self):
"""Return the last five published questions."""
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
def get_queryset(self):
"""Exclude questions that aren't published yet."""
return Question.objects.filter(pub_date__lte=timezone.now())
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
def vote(request, question_id):
return HttpResponse(f"You're voting on question {question_id}.")
- IndexView: Displays a list of the latest questions.
- DetailView: Shows the details of a specific question and its choices.
- ResultsView: Displays the results of a poll after voting. The vote() function handles the user's vote submission.
7. Configuring URLs
I added URL patterns to the urls.py file in the polls app to link each view to a specific URL.
# urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
8. Creating Templates for Views
Finally, I created HTML templates to display the questions and results. The templates are placed in the polls/templates/polls/ folder.
index.html
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset>
<legend><h1>{{ question.question_text }}</h1></legend>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
result.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>
<a href="{% url 'polls:detail' question.id %}">Vote again?</
Running the Application
To test the application, I ran the development server:
python manage.py runserver
Navigating to http://127.0.0.1:8000/polls/ displayed the list of polls, and I could view details, vote, and see results.
Over the past two weeks, I learned how to set up Django, create a project, and build a fully functioning poll app. It was fascinating to see how everything connects in Django, from models to views to templates. This has been a great experience, and I’m excited to learn more about Django's powerful features!
Posted on September 16, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.