Voting System Project Using Django Framework



The Voting System Project is a small web application created with Django framework for the purpose of organizing the polls. This is a mobile application that enables the users to browse through the polls they are interested in and cast their vote from the options available as well as view the outcome of the voting. The admin interface allows the creation, listing and deletion of poll questions and choices without the need of the users interface. This project makes it very clear to the developer on what Django is all about, how its manages models, how it handles views and even how it renders templates.

Installation

To start and run the Voting System Project, follow these installation steps −

1. Python and pip are installed

  • Python 3.11 or higher is required.
  • pip is the Python package installer

2. Install Django

Open your terminal command to install Django

pip install django

3. Set Up a Django Project

  • Open VS code and create a new folder for your project
  • Navigate to this directory in your terminal and run:
  • Code: django-admin startproject voting_system

Create a Django App

1. Create an App

Navigate into the voting_system directory

cd voting_system

Create a new app called polls −

python manage.py startapp polls

2. Define Models: polls/models.py

from django.db import models
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

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

3. Apply Migrations

Go to your terminal and write this −

python manage.py makemigrations
python manage.py migrate

4. File Structure

File Structure

5. Create Views in polls/views.py

from django.shortcuts import render, get_object_or_404
from .models import Question, Choice
from django.http import HttpResponse

def homepage(request):
   return HttpResponse("Welcome to the Voting System!")

def index(request):
   latest_question_list = Question.objects.order_by('-pub_date')[:5]
   context = {'latest_question_list': latest_question_list}
   return render(request, 'polls/index.html', context)

def detail(request, question_id):
   question = get_object_or_404(Question, pk=question_id)
   return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
   question = get_object_or_404(Question, pk=question_id)
   return render(request, 'polls/results.html', {'question': question})

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 += 1
      selected_choice.save()
      return render(request, 'polls/results.html', {'question': question})

6. Configure URLs in polls/urls.py

from django.urls import path
from . import views

app_name = 'polls'
urlpatterns = [
   path('', views.index, name='index'),
   path('question/<int:question_id>/', views.detail, name='detail'),
   path('question/<int:question_id>/results/', views.results, name='results'),
   path('question/<int:question_id>/vote/', views.vote, name='vote'),
   path('homepage/', views.homepage, name='homepage'),
]

7. Update Project URLs in voting_system/urls.py

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
   path('admin/', admin.site.urls),
   path('', include('polls.urls')),
]

8. Create Templates

Base Template (polls/templates/polls/base.html)

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>{% block title %}Voting System{% endblock %}</title>
   <link rel="stylesheet" href="{% static 'polls/styles.css' %}">
</head>
<body>
<header>
<h1>Voting System</h1>
<nav>
<ul>
   <li><a href="{% url 'polls:index' %}">View Available Polls</a></li>
   <li><a href="{% url 'polls:homepage' %}">Home</a></li>
</ul>
</nav>
</header>
<main>
   {% block content %}{% endblock %}
</main>
</body>
</html>

Index Template (polls/templates/polls/index.html)

{% extends 'polls/base.html' %}
{% block title %}Polls{% endblock %}
{% block content %}
<h2>Latest Polls</h2>
<ul>
   {% for question in latest_question_list %}
   <li>
      <a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a>
   </li>
   {% endfor %}
</ul>
{% endblock %}

Detail Template (polls/templates/polls/detail.html)

{% extends 'polls/base.html' %}
{% block title %}Poll Details{% endblock %}
{% block content %}
<h2>{{ question.question_text }}</h2>
<form action="{% url 'polls:vote' question.id %}" method="post">
   {% csrf_token %}
   {% for choice in question.choice_set.all %}
   <input type="radio" id="choice{{ choice.id }}" name="choice" value="{{ choice.id }}">
   <label for="choice{{ choice.id }}">{{ choice.choice_text }}</label><br>
   {% endfor %}
   <input type="submit" value="Vote">
</form>
<p><a href="{% url 'polls:index' %}">Back to Polls</a></p>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
{% endblock %}

Results Template (polls/templates/polls/results.html)

{% extends 'polls/base.html' %}
{% block title %}Poll Results{% endblock %}
{% block content %}
<h2>{{ question.question_text }}</h2>
<ul>
   {% for choice in question.choice_set.all %}
   <li>{{ choice.choice_text }}: {{ choice.votes }} votes</li>
   {% endfor %}
</ul>
<p><a href="{% url 'polls:index' %}">Back to Polls</a></p>
{% endblock %}

9. Create Static Files

Add your CSS file (polls/static/polls/styles.css) to style the application.

Example

body {
   font-family: Arial, sans-serif;
   margin: 0;
   padding: 0;
   background-color: #f4f4f4;
}

header {
   background-color: #333;
   color: white;
   padding: 1rem;
   text-align: center;
}

nav ul {
   list-style: none;
   padding: 0;
}

nav ul li {
   display: inline;
   margin: 0 1rem;
}

nav ul li a {
   color: white;
   text-decoration: none;
}

main {
   padding: 1rem;
}

h2 {
   color: #333;
}

form {
   background-color: #fff;
   padding: 1rem;
   border-radius: 5px;
   box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

form input[type="submit"] {
   background-color: #333;
   color: white;
   border: none;
   padding: 0.5rem 1rem;
   border-radius: 5px;
   cursor: pointer;
}

10. Admin.py file

from django.contrib import admin
from .models import Question, Choice, Vote

class ChoiceInline(admin.TabularInline):
   model = Choice
   extra = 2  # Number of empty choice fields to display

class QuestionAdmin(admin.ModelAdmin):
   fieldsets = [
      (None, {'fields': ['question_text']}),
      ('Date Information', {'fields': ['pub_date'], 'classes': ['collapse']}),
   ]
   inlines = [ChoiceInline]
   list_display = ('question_text', 'pub_date')
   list_filter = ['pub_date']
   search_fields = ['question_text']

class ChoiceAdmin(admin.ModelAdmin):
   list_display = ('choice_text', 'votes', 'question')
   list_filter = ['question']
   search_fields = ['choice_text']

class VoteAdmin(admin.ModelAdmin):
   list_display = ('voter_name', 'choice')
   list_filter = ['choice']
   search_fields = ['voter_name']

admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice, ChoiceAdmin)
admin.site.register(Vote, VoteAdmin)

11. Settings.py

Django settings for voting_system project.

Generated by 'django-admin startproject' using Django 5.1.

For more information on this file, see
https://docs.djangoproject.com/en/5.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.1/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-ahjvi2=3zf5j8+%71b6hpn+5!m0+hggf4+343(i8yp%qw^^d20'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
   'polls',
]

MIDDLEWARE = [
   'django.middleware.security.SecurityMiddleware',
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.common.CommonMiddleware',
   'django.middleware.csrf.CsrfViewMiddleware',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.messages.middleware.MessageMiddleware',
   'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'voting_system.urls'

TEMPLATES = [
   {
      'BACKEND': 'django.template.backends.django.DjangoTemplates',
      'DIRS': [],
      'APP_DIRS': True,
      'OPTIONS': {
         'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',
            'django.contrib.messages.context_processors.messages',
          ],
      },
   },
]

WSGI_APPLICATION = 'voting_system.wsgi.application'

# Database
# https://docs.djangoproject.com/en/5.1/ref/settings/#databases

DATABASES = {
   'default': {
      'ENGINE': 'django.db.backends.sqlite3',
      'NAME': BASE_DIR / 'db.sqlite3',
   }
}

# Password validation
# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
   {
      'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
   },
   {
      'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
   },
   {
      'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
   },
   {
      'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
   },
]

# Internationalization
# https://docs.djangoproject.com/en/5.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.1/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

12. Create a Superuser

Now open your terminal and write this code −

python manage.py createsuperuser
Python Code

OUTPUT

Before runserver you can write this  Python Shell

You can also interact with the models using the Django shell. Here’s an example −

Open the Django Shell

python manage.py shell

Create a Question and Choices

from polls.models import Question, Choice
from django.utils import timezone

# Create a new question
q = Question(question_text="What's your favorite color?", pub_date=timezone.now())
q.save()

# Add some choices to the question
q.choice_set.create(choice_text='Red', votes=0)
q.choice_set.create(choice_text='Blue', votes=0)
q.choice_set.create(choice_text='Green', votes=0)
q.choice_set.create(choice_text='Yellow', votes=0)

Exit the Shell

exit()

LOOK at that output −

Python Output

After completing the setup and code implementation, you can write this for run the server in your window −

python manage.py runserver

Once the server is running, go to http://127.0.0.1:8000/ in your web browser in Incognito tab ,You'll see the landing page of the voting system, where you can view available polls, vote, and check the results.

Python Output

After you search you will this page appear in your screen −

Python Output

You can add more question we add only one question click the question −

Python Output

You have to write your name otherwise it will not work, you can not vote −

Python Output

Then click vote option you will see who vote which color −

Python Output

Again you can vote from different user −

Python Output

Now the final result −

Python Output

Summary

The Voting System Project is quite useful for how to design the poll application with the help of the Django framework. It shows how you can apply Djangos model-view-template (MVT) model to develop an internet based application for viewing polls, voting and viewing results. In the project, one gets to work on the basics of Django like defining models, map URLs, view functions, and rendering templates.

Conclusion

Nonetheless, this project is important to learn Django from the ground up especially for those who are new in web development using Django. By going through this procedure, one will be able to learn the process of establishing a Django project as well as creating and managing models in the project to build a successful web application. The Voting System Project is a good background for additional applications, and it is interesting to try in Django further.

python_projects_from_basic_to_advanced.htm
Advertisements