使用 Django 框架的投票系统项目一
我们将使用 Django 创建一个 pollster(投票系统)Web 应用程序。该应用程序将进行一系列问题以及许多选择。用户将被允许通过选择一个选项来对该问题进行投票。根据答案,将计算总票数并将其显示给用户。用户还可以直接在网站上查看具体问题的总票数结果。我们还将构建该项目的管理部分。管理员用户将被允许在应用程序中添加问题和管理问题。
先决条件: Python
知识和 Django框架基础知识。系统中应安装Python
。Visual Studio Code
或任何用于处理该应用程序的代码编辑器。
项目中使用的技术: Django框架和Django默认自带的SQLite
数据库。
项目实施
创建项目
步骤 1:在您的目录中创建一个空文件夹pollster_project
。
步骤 2:
现在切换到您的文件夹并使用以下命令在此文件夹中创建虚拟环境。
pip install pipenv
pipenv shell
步骤 3:
将在上述步骤的文件夹中创建一个Pipfile 。现在使用以下命令在您的文件夹中安装 Django。
pipenv install Django
步骤 4:
现在我们需要建立Django项目。在您的文件夹中运行以下命令并启动 Django 项目。
django-admin startproject pollster
将创建一个名为pollster的新文件夹。使用以下命令切换到 pollster 文件夹。
cd pollster
文件夹结构看起来像这样。
在这里,您可以使用以下命令启动服务器,并在浏览器中 使用http://127.0.0.1:8000/
检查应用程序是否正在运行。
python manage.py runserver
步骤 5:
使用以下命令 创建应用程序“ polls ”
python manage.py startapp polls
下面是在项目中创建“polls”应用程序后的文件夹结构。
创建模型
步骤 1:
在您的 models.py 文件中编写下面给出的代码,以在数据库中创建两个表。一是“问题”,二是“选择”。
“问题”将有两个字段“question_text”和“pub_date”。Choice 具有三个字段:“question”、“choice_text”和“votes”。每个选项都与一个问题相关联。
from django.db import models
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
步骤 2:
转到settings.py文件并在列表中的 INSTALLED_APPS 中写下以下代码以将该应用程序包含在我们的项目中。这将引用 polls -> 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',
]
步骤 3:
我们对数据库进行了更改并创建了一些表,但为了反映这些更改,我们需要在此处创建迁移,然后 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:xyz@example.com
最后一步是输入密码。我们需要输入密码两次,第二次是对第一次的确认。
密码: ******
密码(再次): ******
超级用户创建成功。
现在我们可以使用相同的命令python manage.py runserver
来运行服务器,并且可以通过浏览 URL `http://127.0.0.1:8000/admin` 来检查我们的管理面板。
步骤 2:
在admin.py文件中,我们将编写下面给出的代码,将每个问题与要选择的选项对应起来。此外,我们将编写代码来更改站点标题、站点标题和索引标题。完成此操作后,我们可以从管理面板添加问题和问题选项。
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, )))
创建模板
步骤 1:
按照下面给出的步骤创建页面的正面布局。
- 在顶级民意调查文件夹(民意调查和民意调查旁边)中创建一个文件夹“模板”,即民意调查->模板。
- 在模板文件夹内创建“ base.html ”文件。我们将在此文件中定义应用程序的头部、主体和导航栏。
- 在“templates”文件夹中创建另一个文件夹“ polls ”。在“polls”文件夹中创建三个文件“ index.html ”、“ results.html ”和“ detail.html ”。
文件夹结构将如下图所示(我们突出显示了在“创建视图即 urls.py”和“创建模板”部分中创建的文件)
步骤 2:
默认情况下,Django 将在“民意调查”应用程序内搜索“模板”,但我们在民意调查应用程序外部创建了一个全局“模板”文件夹。因此,为了使其正常工作,我们需要在 settings.py 文件中定义“模板”文件夹路径。打开settings.py文件并在“模板”列表中添加下面给出的代码。为了使给定的代码正常工作,请在 settings.py
中添加“ import os ”。
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 %}
步骤4:
打开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 %}
步骤 5:
打开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
文件中包含 head 和 body 标签。我们可以将这些代码编写在一个文件base.html
中,并且可以为我们的页面提供布局。我们还将在此页面上添加导航栏(_navbar.html 文件)。因此,打开“template”文件夹中的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>