Django 开发投票系统

主要参考官方文档

Windows  10

Python 23.5

Django 1.9

1.创建项目(mysite)与应用(polls

D:python>django-admin.py startproject mysite

D:python>cd mysite

D:pythonmysite>python manage.py startapp polls

创建app后将app加入到setting中,打开mysite/setting.py,将polls这个应用添加进去

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

2.创建模型

打开polls/models.py

import datetime
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils import timezone

# Create your models here.
# 问题
@python_2_unicode_compatible
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    
    def was_published_recently(self):
        now = timezone.now()
        return timezone.now()-datetime.timedelta(days=1) <= self.pub_date <= now

    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'
    
    def __str__(self):
        return self.question_text

# 选择
@python_2_unicode_compatible  
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

运行命令:python manage.py makemigrations 和python manage.py migrate全数据库生成相应的表

3.后台管理

打开polls/admin.py,

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

# Register your models here.

class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']}),
    ]
    inlines = [ChoiceInline]

    list_filter = ['pub_date']
    list_display = ('question_text', 'pub_date', 'was_published_recently')
    search_fields = ['question_text']

admin.site.register(Question, QuestionAdmin)

4.编写视图函数(展示)

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from .models import Question, Choice
from django.core.urlresolvers import reverse
from django.views import generic
from django.utils import timezone

# Create your views here.

# 展示所有问题
class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'


    def get_queryset(self):
        #return the last five published question
        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):
        """
        Excludes any questions that aren't published yet.
        """
        return Question.objects.filter(pub_date__lte=timezone.now())
# 查看结果
class ResultsView(generic.DeleteView):
    model = Question
    template_name = 'polls/detail.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):
    # 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,)))

5.模板

视图函数处理的结果通过模板展示出来

detail.html

<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<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>

index.html

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

results.html

<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>

6.url分发

不同的url在这里进行分发到不同的函数处理

mysite/urls.py

from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', admin.site.urls),
]

再次分发

polls/urls.py

#coding:utf-8
#!/usr/bin/env python

from django.conf.urls import url
from . import views

app_name = 'polls'
urlpatterns = [
               # ex: /polls/
               url(r'^$', views.IndexView.as_view(), name='index'),
               # ex: /polls/5/
               url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
               # /polls/5/results/
               url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
               # /polls/5/vote/
               url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
               ]

输入命令python manage.py runserver,运行系统

登陆后:

不登陆,可以查看到相应的问题,选中相应的小圆点,点击vote可进行投票。

原文地址:https://www.cnblogs.com/Andy963/p/6062145.html