Django 中的访客投票唯一一次投票
在本文中,我们将介绍 Django 中如何实现一个访客只能投票一次的投票系统。投票系统是一个常见的功能,在很多网站和应用程序中都有应用,例如在线调查、选举投票等。为了保证投票的公平性和准确性,我们需要确保每个访客只能投票一次。在 Django 中,我们可以通过使用 Session 和 Cookie 来实现这一功能。
阅读更多:Django 教程
创建投票模型
首先,我们需要创建一个投票模型来存储投票的数据。在 Django 中,可以使用 Django 模型(Model)来表示数据库表,并将其映射到数据库中。我们可以创建一个名为 “Poll” 的模型,并添加一些字段来存储投票的相关信息,例如投票主题、选项和计数器。
from django.db import models
class Poll(models.Model):
question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
上述代码定义了两个模型类,Poll
表示投票主题,Choice
表示投票选项。Poll
模型有一个问题字段 question
,一个发布日期字段 pub_date
。Choice
模型有一个投票外键 poll
,表示该选项属于哪个投票;一个选项文本字段 choice_text
;以及一个投票计数器字段 votes
。
创建投票视图
接下来,我们需要创建投票视图,即用户在浏览器中看到和操作的部分。我们可以使用 Django 的视图来处理和响应用户的请求。在这个投票系统中,我们将实现一个投票列表页、投票详情页和投票结果页。
首先,我们创建一个投票列表页的视图。
from django.shortcuts import render
from .models import Poll
def poll_list(request):
polls = Poll.objects.all()
return render(request, 'polls/poll_list.html', {'polls': polls})
在上述代码中,我们首先导入了 render
函数和 Poll
模型。然后,我们定义了一个 poll_list
视图函数,该函数接受一个 request
参数,表示用户的请求。在视图函数中,我们使用 Poll.objects.all()
查询所有的投票,并将结果传递给模板。最后,我们使用 render
函数渲染一个名为 poll_list.html
的模板,并将 polls
传递给模板。
接下来,我们创建投票详情页的视图。
from django.shortcuts import get_object_or_404, render
from .models import Poll
def poll_detail(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
return render(request, 'polls/poll_detail.html', {'poll': poll})
在上述代码中,我们首先导入了 get_object_or_404
函数和 Poll
模型。然后,我们定义了一个 poll_detail
视图函数,该函数接受一个 request
参数和一个 poll_id
参数,表示用户的请求和投票的 ID。在视图函数中,我们使用 get_object_or_404
函数通过投票的 ID 查询该投票,并将结果传递给模板。最后,我们使用 render
函数渲染一个名为 poll_detail.html
的模板,并将 poll
传递给模板。
最后,我们创建投票结果页的视图。
from django.shortcuts import get_object_or_404, render
from .models import Poll
def poll_results(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
return render(request, 'polls/poll_results.html', {'poll': poll})
在上述代码中,我们重复了导入语句和 get_object_or_404
函数。然后,我们定义了一个 poll_results
视图函数,该函数接受一个 request
参数和一个 poll_id
参数,表示用户的请求和投票的 ID。在视图函数中,我们使用 get_object_or_404
函数通过投票的 ID 查询该投票,并将结果传递给模板。最后,我们使用 render
函数渲染一个名为 poll_results.html
的模板,并将 poll
传递给模板。
投票限制
为了实现每个访客只能投票一次的功能,我们可以使用 Django 的 Session 和 Cookie 来追踪已投票的访客。当用户投票时,我们将在用户的 Session 中存储一个标记,表示该用户已经投过票了。
首先,我们需要修改投票详情页的视图函数,以便在用户投票后将标记存储在 Session 中。
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from .models import Poll
def poll_detail(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
if request.method == 'POST':
choice_id = request.POST.get('choice')
if choice_id:
choice = poll.choice_set.get(pk=choice_id)
choice.votes += 1
choice.save()
request.session['voted'] = True
return HttpResponseRedirect(reverse('poll_results', args=(poll.id,)))
return render(request, 'polls/poll_detail.html', {'poll': poll})
在上述代码中,我们首先导入了 get_object_or_404
函数、HttpResponseRedirect
类和 reverse
函数。然后,我们在视图函数中增加了一个条件判断:当请求方法为 POST 且用户选择了一个选项时,我们将为该选项的投票计数器加一,并将标记 voted
存储在 Session 中。最后,我们使用 HttpResponseRedirect
类重定向到投票结果页。
接下来,我们需要修改投票结果页的视图函数,以便在用户已投票时显示提示信息。
from django.shortcuts import get_object_or_404, render
from .models import Poll
def poll_results(request, poll_id):
poll = get_object_or_404(Poll, pk=poll_id)
voted = request.session.get('voted', False)
return render(request, 'polls/poll_results.html', {'poll': poll, 'voted': voted})
在上述代码中,我们增加了一个变量 voted
,表示用户是否已投票。我们通过 request.session.get('voted', False)
获取 Session 中的标记,如果不存在则默认为 False
。然后,我们将 voted
传递给模板。
创建投票模板
接下来,我们需要创建投票相关的模板,以便呈现给用户。
首先,我们创建投票列表页的模板 poll_list.html
。
{% for poll in polls %}
<h2>{{ poll.question }}</h2>
<a href="{% url 'poll_detail' poll.id %}">Vote</a>
{% endfor %}
在上述代码中,我们使用了 Django 的模板语法。首先,我们使用了一个 for
循环来遍历所有的投票。然后,我们使用 {{ poll.question }}
输出投票的问题。接下来,我们使用 {% url 'poll_detail' poll.id %}
创建了一个链接,链接到投票详情页,并将投票的 ID 作为参数传递过去。最后,我们使用 {% endfor %}
结束了循环。
接下来,我们创建投票详情页的模板 poll_detail.html
。
<h2>{{ poll.question }}</h2>
{% if voted %}
<p>You have already voted.</p>
{% else %}
<form action="{% url 'poll_detail' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.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 %}
<button type="submit">Vote</button>
</form>
{% endif %}
在上述代码中,我们首先输出了投票的问题。然后,我们使用 {% if voted %}
判断用户是否已经投票,如果是则输出提示信息“You have already voted.”,否则显示投票表单。在表单中,我们使用了一个循环来遍历投票的选项,并使用 <input type="radio">
和 <label>
创建了单选框和选项文本。注意,我们为每个选项的 ID 和名称添加了唯一标识符,以确保它们的唯一性。最后,我们使用了一个提交按钮来提交投票。
最后,我们创建投票结果页的模板 poll_results.html
。
<h2>{{ poll.question }}</h2>
{% for choice in poll.choice_set.all %}
<p>{{ choice.choice_text }}: {{ choice.votes }}</p>
{% endfor %}
在上述代码中,我们首先输出了投票的问题。然后,我们使用一个循环来遍历投票的选项,并输出选项的文本和投票计数器的值。最后,我们使用了 {% endfor %}
结束了循环。
总结
在本文中,我们介绍了如何使用 Django 创建一个访客只能投票一次的投票系统。我们首先创建了投票模型,用于存储投票的相关信息。然后,我们创建了投票视图,包括投票列表页、投票详情页和投票结果页。最后,我们使用 Session 和 Cookie 来限制每个访客只能投票一次。通过这些步骤,我们可以轻松地实现一个功能完善的投票系统。
希望本文对你理解 Django 中的访客投票唯一一次投票有所帮助。如果你有任何问题或疑问,请随时在下方留言。谢谢阅读!