Setting Up Django and Building a Poll App: My Last Two Weeks of Work

ashley_obano_71cd63fedc66

Ashley Obano

Posted on September 16, 2024

Setting Up Django and Building a Poll App: My Last Two Weeks of Work

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

Enter fullscreen mode Exit fullscreen mode

Step 2: Install Django
Once the environment was activated, I installed Django.

pip install django

Enter fullscreen mode Exit fullscreen mode

I then confirmed the installation by running:

django-admin --version

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

I added the new app to INSTALLED_APPS in mysite/settings.py:

INSTALLED_APPS = [
    # other installed apps
    'polls',
]

Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode

5. Creating the Database and Running Migrations
Next, I created the database and applied migrations:

python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

I then created migration files for the polls app:

python manage.py makemigrations polls
python manage.py migrate

Enter fullscreen mode Exit fullscreen mode

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}.")

Enter fullscreen mode Exit fullscreen mode
  • 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'),
]

Enter fullscreen mode Exit fullscreen mode

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 %}

Enter fullscreen mode Exit fullscreen mode

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>

Enter fullscreen mode Exit fullscreen mode

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?</

Enter fullscreen mode Exit fullscreen mode

Running the Application
To test the application, I ran the development server:

python manage.py runserver

Enter fullscreen mode Exit fullscreen mode

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!

💖 💪 🙅 🚩
ashley_obano_71cd63fedc66
Ashley Obano

Posted on September 16, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related