用django寫了一個《攝影作品》在線評比投票系統

N多年前,曾經用PHP爲公司工會寫了一個《工會換屆選舉投票系統》。那時候因爲個人愛好,在自學PHP編程。有一天工會主席找我,希望使用網絡投票方式選出新一屆工會委員。我硬着頭皮接下了任務,花了一個星期才完成。

3年前,EE委員會的老潘找我,希望我能幫忙做一個《三八節攝影作品》評比投票系統。因爲工作忙的原因,就找到百度免費的《問卷調研》這個在線工具,總算是應付過去。

昨天,老潘又提起《攝影作品》在線投票評比的事,還是希望我能幫忙,本想這一次還是用百度的《問卷調研》這個工具,可是已經不能免費使用了,瞭解到至少要支付RMB 1000元,因爲經費緊張,所以另想辦法。

今天,放假,因爲疫情,只能待在家裏,於是決定自己寫一個《攝影作品》投票系統給老潘。花了一個白天,構思、設計後臺數據庫,編寫代碼,測試。總算ok。

系統使用了django2.1.5,  mysql5.7,

一、models.py

from django.db import models

# Create your models here.

class qtype(models.Model):
    name=models.CharField(max_length=20)

    def __str__(self):
        return self.name

class question(models.Model):
    qtext=models.CharField(max_length=200)
    qtype=models.ForeignKey('qtype',to_field='id',on_delete=False)
    largevote=models.IntegerField(default=5,verbose_name='最多可選')

    def __str__(self):
        return self.qtext

class choiceitem(models.Model):
    ctext=models.CharField(max_length=40)
    question=models.ForeignKey('question',to_field='id',on_delete=False)
    image=models.ImageField(upload_to='vote',verbose_name='相片')

    def __str__(self):
        return self.ctext

class voterecord(models.Model):
    email=models.EmailField(max_length=50)
    choiceitem=models.ForeignKey('choiceitem',to_field='id', on_delete=False)

 

二、views.py

from django.shortcuts import render
from django.http import HttpResponse,HttpResponseRedirect
from vote.models import question,qtype,choiceitem,voterecord
from django.views.decorators.csrf import csrf_exempt
from random import shuffle
from django.contrib import messages
from django.utils.safestring import mark_safe
# Create your views here.



@csrf_exempt
def voteindex(request):
    if request.method=='GET':
        return render(request,'voteindex.html')
    if request.method=='POST':
        if len(request.POST.get('email'))<13:
            messages.info(request,'郵件地址不正確!')
            return HttpResponse("<br><br><h2><p align=center class=text-primary>郵件地址不正確,<a href='javascript:history.back(-1);'>返回上一頁</a></p></h2>")
        request.session['email']=request.POST.get('email')
        print(request.session['email'])
        return HttpResponseRedirect('./showquestion')





@csrf_exempt
def showquestion(request):
    #判斷是否投過票? session值判斷
    voted = request.session.get('voted')
    if voted == 'voted':
        return HttpResponse('<br><br><h2><p align=center class=text-primary>你已經投過票了!請勿重複投票!</p></h2>')

    email = request.session.get('email',None)
    if  email==None or len(email)<13:
            messages.info(request,'郵件地址不正確!')
            return HttpResponseRedirect('/vote/')
    if request.method=='GET':


        lists=choiceitem.objects.filter(question_id=1).values('id','ctext','question__qtext','question__largevote','image')
        ll=list(lists)
        shuffle(ll)
        return render(request,'showquestion.html',locals())
    if request.method=='POST':

        vote=request.POST.getlist('vote')
        if len(vote)==0:
            return HttpResponse('<br><br><h2><p align=center class=text-primary>投票不成功!勾選的作品數:' + str(
                len(vote)) +"!請積極參與投票,<a href='javascript:history.back(-1);'>返回上一頁</a></p></h2>")

        largevote=request.POST.get('largevote')
        email=request.session.get('email')
        print(largevote)
        print(vote)
        #判斷勾選的數量是否大與容許選擇的數量
        if len(vote) > int(largevote):
            return HttpResponse('<br><br><h2><p align=center class=text-primary>投票不成功!勾選的作品數:'+str(len(vote))+',已經超過最大可選數:'+largevote+"!<a href='javascript:history.back(-1);'>返回上一頁</a></p></h2>")

        else:
            #投票記錄voterecord裏是否有相同的郵件地址?
            result=voterecord.objects.filter(email=email)
            if result:
                #有相同的郵件地址,提示已經投過票
                return HttpResponse('<br><br><h2><p align=center class=text-primary>你已經投過票了!請勿重複投票!</p></h2>')
            for l in vote:
                voterecord.objects.create(email=email,choiceitem_id=int(l))

        request.session['voted']='voted'
        return HttpResponse('<br><br><h2><p align=center class=text-primary>投票成功!投票結果稍後公佈。</a></p></h2>"')

 

三、模板

 

{% load staticfiles %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <!-- 引入 Bootstrap -->
      <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

      <!-- HTML5 Shiv 和 Respond.js 用於讓 IE8 支持 HTML5元素和媒體查詢 -->
      <!-- 注意: 如果通過 file://  引入 Respond.js 文件,則該文件無法起效果 -->
      <!--[if lt IE 9]>
         <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
         <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
      <![endif]-->
</head>
<body background="/static/media/vote/background.jpg" style="backgrounp-size:cover">
<script src="/static/jquery-2.1.4.js"></script>
<div class="container">
   <div class="row clearfix">
      <div class="col-md-12 column">
         <div class="page-header">
            <h1>
               <p class="text-primary b">優秀攝影作品評比投票 <small>羅湖辦公室EE委員會</small></p>
            </h1>
         </div>
         <div ><h4>{{ ll.0.question__qtext }}(多項選擇,最多可以勾選{{ ll.0.question__largevote }}個作品!) </h4></div>

<form name="votefor" action="#" method="post">
   {% csrf_token %}
<table class="table table-bordered">

 <tbody>
           {% if ll %}
         <input type="text"  name="largevote" value="{{ ll.0.question__largevote }}" hidden>
           <tr >
             {% for l in ll %}
             <td nid="{{ l.id }}" align="center" style="vertical-align: bottom;">
             <span style="vertical-align: middle">
                 <img  src="{% static '/media/' %}{{ l.image}}" alt="picture" width="350" >

                 <p></p>
           <ol class="list-unstyled">
               <li>

            </li>
            <li>
               <font color="blue"> {{ forloop.counter  }}: [{{ l.ctext }}]</font>
            </li>
            <li>

                    <a class="btn primary" onclick="testajax(this);" href="#">查看大圖</a>
                    <!--
               <a onclick="testajax(this);" href="#" >放入購物車</a>

               -->
            </li>

                <li>
               投一票 : <input type="checkbox" name="vote" value="{{ l.id }}">
            </li>

           </ol>
       </span>
           </td>


              {% if forloop.counter|divisibleby:"3"%}
               </tr>
           <tr>
               {% endif %}
            {% endfor %}
           </tr>
 {% endif %}
</tbody>
</table>


<input type="submit" value="提交"> <input type="reset" value="重置">
</form>


      </div>
   </div>


   <br>
<p></p>
<hr/>
<div> <p align="center" class="text-primary">---本投票系統由xxx提供技術支持,歡迎使用--- </p></div>
</div>


</body>
</html>

四、以下是效果圖

 

1

 

五、特點

圖片的排序是隨機的,杜絕重複投票--用session標誌和識別是否重複投票,多項選擇,勾選個數不能大於規定的數量。在後臺設置標題和圖片上傳,後臺設置可選數量。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章