We will go through setting up a Django project from scratch to create a simple polling application. This guide will cover everything from installing Python and Django to configuring your app with models, views, and templates. Along the way, we will build a feature that lets users vote in a poll, and we will explore key concepts like generic views, models, and URL routing.
Step 1: Installing Python and Setting Up a Virtual Environment
Before you start with Django, make sure you have Python installed on your machine. If you don’t have it installed, you can download Python from python.org.
To keep your project’s dependencies isolated, it’s best to use a virtual environment.
# Install virtualenv if you don't have it
pip install virtualenv
# Create a virtual environment
virtualenv venv
# Activate the virtual environment
venv\Scripts\activate
Step 2: Installing Django and Starting a Project
With your virtual environment activated, install Django:
pip install django
Now, create a new Django project called mysite:
django-admin startproject mysite
This command creates a mysite directory that contains your project files.
Step 3: Creating the Polls App
Django follows a modular approach, and every feature in Django is usually built inside an "app". We will create an app called polls.
cd mysite
python manage.py startapp polls
Next, register the polls app in mysite/settings.py by adding it to the INSTALLED_APPS list:
INSTALLED_APPS = [
# other apps...
'polls',
]
Step 4: Defining Models for Questions and Choices
In polls/models.py, we will define two models: Question and Choice. Each Question will have several Choices that users can vote on.
from django.db import models
from django.utils import timezone
import datetime
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
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
Step 5: Creating and Migrating the Database
We will be using SQLite for our database, which is the default for Django. The configuration can be found in mysite/settings.py under the DATABASES section:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
After setting up the models, you need to generate the migrations and apply them to create the database schema:
python manage.py makemigrations
python manage.py migrate
Step 6: Creating Views for Polls
We will use Django’s generic views to simplify the process of creating list and detail views. In polls/views.py, define views for listing questions, showing details of a question, and displaying results.
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.db.models import F
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 Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'
def get_queryset(self):
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):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes = F('votes') + 1
selected_choice.save()
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
Step 7: Mapping URLs to Views
In polls/urls.py, define the URL patterns for our app, which will map the URL paths to the views we just created.
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'),
]
Then, include the polls/urls.py in the main mysite/urls.py:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
Step 8: Creating Templates
In polls/templates/polls/, create the HTML templates. First, index.html will display the list of questions:
{% load static %}
<link rel="stylesheet" href="{% static 'polls/style.css' %}">
{% 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 %}
Next, the detail.html template will display the voting form for a question:
<h1>{{ question.question_text }}</h1>
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% 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 %}
<input type="submit" value="Vote">
</form>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
Lastly, results.html will display the voting results:
<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?</a>
Step 9: Running the Development Server
Now that everything is set up, you can start the Django development server:
python manage.py runserver
Top comments (0)