使用Django框架的投票系统项目
项目名称: Pollster(投票系统)网络应用,使用Django框架
应用类型(类别):网络应用。
介绍:我们将使用Django创建一个投票器(投票系统)网络应用。这个应用程序将进行一系列的问题,并有许多选择。用户将被允许通过选择一个选项来为该问题投票。根据答案,总票数将被计算出来并显示给用户。用户也可以在网站上直接查看特定问题的总票数结果。我们还将建立这个项目的管理部分。管理员用户将被允许在应用程序中添加问题和管理问题。
前提条件:具备Python知识和Django框架的基础知识。系统中应安装Python。Visual studio代码或任何代码编辑器来处理应用程序。
项目中使用的技术: Django框架和Django默认提供的SQLite数据库。
项目的实现
创建项目
第1步:在你的目录中创建一个空的文件夹pollster_project。
第2步:现在切换到你的文件夹,使用以下命令在这个文件夹中创建一个虚拟环境。
pip install pipenv
pipenv shell
第三步:一个Pipfile将在你的文件夹中创建,从上述步骤开始。现在使用以下命令在你的文件夹中安装Django。
pipenv install django
第四步:现在我们需要建立Django项目。在你的文件夹中运行以下命令,启动一个Django项目。
django-admin startproject pollster
一个名为pollster的新文件夹将被创建。使用以下命令切换到pollster文件夹。
cd pollster
文件夹结构将看起来像这样。
在这里,你可以使用以下命令启动服务器,并在浏览器中使用ur http://127.0.0.1:8000/ 检查应用程序是否运行。
python manage.py runserver
第五步:使用以下命令创建一个应用程序 “polls“。
python manage.py startapp polls
以下是在项目中创建 “民意调查 “应用程序后的文件夹结构。
创建模型
第1步:在你的models.py文件中写下下面的代码,在你的数据库中创建两个表。一个是 “问题”,另一个是 “选择”。问题 “将有两个字段:”question_text “和 “pub_date”。选择有三个字段:’问题’、’选择_文本’和’投票’。每个选择都与一个问题相关联。
from django.db import models
# Create your models here.
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
第二步:进入settings.py文件,在列表中的INSTALLED_APPS中写下以下代码,将该应用纳入我们的项目中。这将引用民意调查 -> apps.py -> PollsConfig类。
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
第三步:我们已经对数据库进行了修改,并创建了一些表,但为了反映这些变化,我们需要在这里创建迁移,然后Django应用程序将存储对我们的模型的变化。运行下面的命令来创建迁移。
python manage.py makemigrations polls
在polls->migrations中,将创建一个文件0001_initial.py,你可以找到我们在models.py文件中创建的数据库表。现在,为了在我们的数据库中插入所有的表,运行下面的命令…
python manage.py migrate
创建一个管理员用户
第1步:运行下面的命令,创建一个可以登录到管理站点的用户。
python manage.py createsuperuser
它将提示我们需要输入的用户名。
Username: geeks123
现在它将提示一个电子邮件地址,我们需要再次在这里输入。
Email address: xyz@example.com
最后一步是输入密码。我们需要输入两次密码,第二次是对第一次的确认。
Password: ******
Password (again): ******
Superuser created successfully.
现在我们可以使用同样的命令python manage.py runserver来运行服务器,我们可以通过浏览网址http://127.0.0.1:8000/admin 来检查我们的管理面板。
第二步:在admin.py文件中,我们将编写下面的代码,将每个问题与选择进行映射。另外,我们将写代码来改变网站的标题,网站的标题和index_title。一旦完成这些,我们就可以在管理面板上添加问题和选择。
from django.contrib import admin
# Register your models here.
from .models import Question, Choice
# admin.site.register(Question)
# admin.site.register(Choice)
admin.site.site_header = "Pollster Admin"
admin.site.site_title = "Pollster Admin Area"
admin.site.index_title = "Welcome to the Pollster Admin Area"
class ChoiceInLine(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [(None, {'fields': ['question_text']}), ('Date Information', {
'fields': ['pub_date'], 'classes': ['collapse']}), ]
inlines = [ChoiceInLine]
admin.site.register(Question, QuestionAdmin)
注意:我们可以在这里通过添加一些问题和这些问题的选择来测试应用程序。
创建视图
现在我们将创建我们应用程序的视图,它将从我们的数据库中获取数据,并将数据呈现在我们应用程序的 “模板 “中(我们将在下一节中创建 “模板 “文件夹和该文件夹中的文件),将其显示给用户。
步骤1 打开views.py文件,写下下面的代码。
from django.template import loader
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from .models import Question, Choice
# Get questions and display them
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)
# Show specific question and choices
def detail(request, question_id):
try:
question = Question.objects.get(pk = question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls / detail.html', {'question': question})
# Get question and display results
def results(request, question_id):
question = get_object_or_404(Question, pk = question_id)
return render(request, 'polls / results.html', {'question': question})
# Vote for a question choice
def vote(request, question_id):
# print(request.POST['choice'])
question = get_object_or_404(Question, pk = question_id)
try:
selected_choice = question.choice_set.get(pk = request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls / detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args =(question.id, )))
第二步:在pollster->polls文件夹下创建一个urls.py文件,为我们在views.py文件中实现的所有方法定义路由(不要与pollster->pollster->urls.py文件内的文件混淆)。下面是urls.py文件的代码…
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.index, name ='index'),
path('<int:question_id>/', views.detail, name ='detail'),
path('<int:question_id>/results/', views.results, name ='results'),
path('<int:question_id>/vote/', views.vote, name ='vote'),
]
创建模板
第1步:按照下面的步骤来创建页面的前部布局。
- 在顶级投票站文件夹(与民意调查和投票站并列)中创建一个文件夹 “模板”,即投票站->模板。
- 在模板文件夹中创建’base.html’文件。我们将在这个文件中定义我们应用程序的头部、主体和导航栏。
- 在’templates’文件夹中创建另一个文件夹’pollls’。在’pollls’文件夹中创建三个文件’index.html’,’results.html’和’detail.html’。
文件夹结构将如下图所示(我们强调了我们在 “创建视图即urls.py “和 “创建模板 “部分所创建的文件)。
第二步:默认情况下,Django会在 “投票 “应用程序中搜索 “模板”,但我们已经创建了一个全局的 “模板 “文件夹,它在投票应用程序之外。因此,为了使其发挥作用,我们需要在settings.py文件中定义 “模板 “文件夹的路径。打开settings.py文件,在 “TEMPLATES “列表中添加下面的代码。
TEMPLATES = [
{
# make changes in DIRS[].
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'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',
],
},
},
]
第3步:打开index.html文件,写下下面的代码。这个文件将显示存储在我们数据库中的问题清单。同时,将向用户显示两个按钮。一个是用于投票(我们将创建一个用于投票的detail.html文件),另一个是用于检查结果**(我们将创建用于结果的results.html文件)。
{% extends 'base.html' %}
{% block content %}
<h1 class ="text-center mb-3">Poll Questions</h1>
{% if latest_question_list %}
{% for question in latest_question_list %}
<div class ="card-mb-3">
<div class ="card-body">
<p class ="lead">{{ question.question_text }}</p>
<a href ="{% url 'polls:detail' question.id %}" class ="btn btn-primary btn-sm">Vote Now</a>
<a href ="{% url 'polls:results' question.id %}" class ="btn btn-secondary btn-sm">Results</a>
</div>
</div>
{% endfor %}
{% else %}
<p>No polls available</p>
{% endif %}
{% endblock %}
第四步:打开detail.html文件,写下下面的代码。这个文件将负责对特定问题进行投票。无论用户从问题列表(index.html文件)中选择什么问题进行投票,该具体问题和问题的选择都将显示在这个页面上。用户将被允许选择一个选项,并通过点击投票按钮进行投票。
{% extends 'base.html' %}
{% block content %}
<a class ="btn btn-secondary btn-sm mb-3" href ="{% url 'polls:index' %}">Back To Polls</a>
<h1 class ="text-center mb-3">{{ question.question_text }}</h1>
{% if error_message %}
<p class ="alert alert-danger">
<strong>{{ error_message }}</strong>
</p>
{% endif %}
<form action ="{% url 'polls:vote' question.id %}" method ="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<div class ="form-check">
<input type ="radio" name ="choice" class ="form-check-input" id ="choice{{ forloop.counter }}"
value ="{{ choice.id }}" />
<label for ="choice{{ forloop.counter }}">{{ choice.choice_text }}</label>
</div>
{% endfor %}
<input type ="submit" value ="Vote" class ="btn btn-success btn-lg btn-block mt-4" />
</form>
{% endblock %}
第五步:打开results.html文件,写下下面的代码。这个文件将显示特定问题的总票数结果,无论用户选择什么问题(从index.html文件)来检查结果。
{% extends 'base.html' %}
{% block content %}
<h1 class ="mb-5 text-center">{{ question.question_text }}</h1>
<ul class ="list-group mb-5">
{% for choice in question.choice_set.all %}
<li class ="list-group-item">
{{ choice.choice_text }} <span class ="badge badge-success float-right">{{ choice.votes }}
vote{{ choice.votes | pluralize }}</span>
</li>
{% endfor %}
</ul>
<a class ="btn btn-secondary" href ="{% url 'polls:index' %}">Back To Polls</a>
<a class ="btn btn-dark" href ="{% url 'polls:detail' question.id %}">Vote again?</a>
{% endblock %}
第6步:让我们为我们的应用程序创建导航栏。在’templates’文件夹中创建一个’partials‘文件夹,然后在’partial’文件夹中创建一个’_navbar.html‘文件。文件结构将是templates->partials->_navbar.html。在这个文件中写上下面的代码。
<nav class ="navbar navbar-dark bg-primary mb-4">
<div class ="container">
<a class ="navbar-brand" href ="/">Pollster</a>
</div>
</nav>
第7步:我们到现在为止还没有在我们创建的每一个HTML文件中包含头部和身体标签。我们可以把这些代码写在一个单独的文件base.html中,我们可以给我们的页面进行布局。我们还将把我们的导航栏(_navbar.html文件)放在这个页面上。因此,打开 “模板 “文件夹中的base.html**文件,写下下面的代码。
<! DOCTYPE html>
<html lang ="en">
<head>
<link rel ="stylesheet" href ="https://stackpath.bootstrapcdn.com / bootstrap / 4.4.1 / css / bootstrap.min.css"
integrity ="sha384-Vkoo8x4CGsO3 + Hhxv8T / Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin ="anonymous">
<title>Pollster {% block title %}{% endblock %}</title>
</head>
<body>
<!--NavBar-->
{% include 'partials/_navbar.html'%}
<div class ="container">
<div class ="row">
<div class =".col-md-6 m-auto">
{% block content %}{% endblock %}
</div>
</div>
</div>
</body>
</html>
创建登陆页面
URL http://127.0.0.1:8000/ 应该为我们的网络应用程序显示一个登陆页。因此,为了创建一个登陆页面,我们将按照下面的步骤进行。
第1步 切换到顶层的pollster文件夹,运行下面的命令,创建一个应用程序’pages‘。
python manage.py startapp pages
以下是 “页面 “应用程序创建后的文件夹结构。
第2步在 “pages “文件夹中打开 “views.py“,即page->views.py。写下下面的代码来访问登陆页面。
from django.shortcuts import render
# Create your views here.
def index(request):
return render(request, 'pages / index.html')
第3步在 “pages “文件夹中创建urls.py文件,即pages->urls.py。写下下面的代码来定义pages->index.html文件的路由(查看步骤1)。
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name ='index'),
]
第四步在 “模板 “文件夹中创建一个文件夹 “页面“。现在在’pages’文件夹中创建一个文件 index.html 。写下下面的代码,向用户显示登陆页面。
{% extends 'base.html' %}
{% block content %}
<div class ="card text-center">
<div class ="card-body">
<h1>Welcome To Pollster</h1>
<p>This is an example Django polling app</p>
<a class ="btn btn-dark" href ="{% url 'polls:index' %}">
View Available Polls</a>
</div>
</div>
{% endblock %}
在应用程序的主urls.py文件中创建路由
我们已经在我们的应用程序中创建了两个应用程序 “投票 “和 “页面”。我们需要在主urls.py文件中定义这两个应用程序的路由,即pollster->pollster->urls.py文件。因此,打开pollster文件夹中的主urls.py文件,写下下面的代码来定义这两个应用程序(’民意调查’和’页面’)的路由。
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('', include('pages.urls')),
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
应用程序的测试
Admin 前端
第1步使用命令python manage.py runserver运行服务器,并浏览URL http://127.0.0.1:8000/admin/。现在输入用户名和密码来登录系统。
第2步点击 “问题 “旁边的 “添加 “按钮。
第2步现在添加问题和这些问题的选择。同时,提及日期和时间,然后点击 “保存 “按钮。你可以根据自己的需要添加问题。你会看到数据库中添加的问题列表。
User 前端
第1步:浏览网址http://127.0.0.1:8000/,你将看到应用程序的登陆页面。点击 “查看可用的民意调查”。
第二步:你将看到问题清单,其中有两个选项 “立即投票 “和 “结果”。从这里你需要选择一个问题并点击’立即投票’按钮。
第三步:一旦完成,选择任何一个选择并点击’投票’按钮。你也可以使用顶部的’返回投票’按钮回到之前的菜单。
你将看到你所选问题的总投票结果。
你也可以通过 “投票问题 “页面的 “结果 “选项查看任何问题的总票数。
Future Scope
该项目可用于在任何领域或行业进行在线投票系统。该项目可以扩展,其他几个功能也可以根据要求加入。人们可以分享意见,他们也可以检查许多用户给予的总投票。
项目库链接
https://github.com/anuupadhyay/pollster-django-crash