核心提示:1、概述当我们在浏览网站时,经常会碰到如对一篇文章进行投票:喜欢、不喜欢还是弃票。投票也用表单提交实现,但与通常表单不同的是,投票提交的表单不需要进行相关的错误验证。2、models.py层投票的数据...
1、概述
当我们在浏览网站时,经常会碰到如对一篇文章进行投票:喜欢、不喜欢还是弃票。投票也用表单提交实现,但与通常表单不同的是,投票提交的表单不需要进行相关的错误验证。
2、models.py层投票的数据结构
在之前篇章功能的基础上(即models层已有数据Video和用户UserProfile)如下:
class Video(models.Model): title = models.CharField(null=True, blank=True, max_length=300) content = models.TextField(null=True, blank=True) url_image = models.URLField(null=True, blank=True) cover = models.FileField(upload_to='cover_image', null=True) editors_choice = models.BooleanField(default=False) def __str__(self): return self.title class UserProfile(models.Model): belong_to = models.OneToOneField(to=User, related_name='profile') profile_image = models.FileField(upload_to='profile_image')
解析:以上数据项是实现网页内容和网页登录用户注册设定的。
因投票功能需要将票关联到用户和将票关联到投票对象,这这张票是谁投的,投给那个对象的。故在model层设计票数据项:
class Ticket(models.Model): voter = models.ForeignKey(to=UserProfile, related_name='voter_ticket') video = models.ForeignKey(to=Video, related_name='video_ticket') VOTER_CHICES = ( ('like','like'), ('dislike', 'dislike'), ('normal', 'normal'), ) choice = models.CharField(choices=VOTER_CHICES, max_length=10) def __str__(self): return str(self.id)
解析:
a、字段voter是针对用户的外键,因用户和票是一对多关系,一个用户可以投票多个多项;
b、字段video是这对Video对象的外键,因一个对象可以投多张票,是一对多关系;
c、字段choice是用户的投票选择:喜欢like、不喜欢dislike和未投票normal。
3、投票的网页显示
1)在视图层views.py实现投票显示视图
def detail(request, id): context = {} vid_info = Video.objects.get(id=id) voter_id = request.user.profile.id like_counts = Ticket.objects.filter(choice='like',video_id=id).count() try: user_ticket_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=id) context['user_ticket'] = user_ticket_for_this_video except : pass context['vid_info'] = vid_info return render(request, 'detail.html', context)
解析:通过request.user.profile.id来获取当前请求的用户,然后与当前请求对象id结合来获取得到当前的票user_ticket_for_this_video;
2)通过模板来加载变量
<p class="ui basic segment container"> <h1 class="ui header">{{ vid_info.title }}</h1> <i class="icon grey unhide"></i> <span style="color:#bbbbbb">10K</span> <span class="" style="color:rgb(226, 226, 226)">|</span> <i class="icon grey checkmark"></i> <span style="color:#bbbbbb">{{ like_counts }} people got it</span> //#01 <p> {{ vid_info.content }} </p> <p class="ui pider"></p> <form class="ui form" action="" method="post"> {% csrf_token %} {% if user_ticket.choice == 'like' %} //#02 <button class="ui red tiny button" type="submit" name="vote" value="normal"> <i class="icon checkmark"></i> Get it! </button> <button class="ui tiny button" type="submit" name="vote" value="dislike"> <i class="icon bomb"></i> Hmmm... </button> {% elif user_ticket.choice == 'dislike' %} <button class="ui tiny button" type="submit" name="vote" value="like"> <i class="icon checkmark"></i> Get it! </button> <button class="ui red tiny button" type="submit" name="vote" value="normal"> <i class="icon bomb"></i> Hmmm... </button> {% else %} <button class="ui tiny button" type="submit" name="vote" value="like"> <i class="icon checkmark"></i> Get it! </button> <button class="ui tiny button" type="submit" name="vote" value="dislike"> <i class="icon bomb"></i> Hmmm... </button> <button class="ui secondary circular tiny right floated pin icon button"> <i class="pin icon"></i> Saved </button> {% endif %} </form> </p>
3、投票的结果存储功能
如上只是显示了在后台对Ticket进行操作后,网页中的投票状态的显示结果。下面将是直接在网页中进行投票,如用户点击投票则结果保存至数据库状态。
1)在views.py层添加投票视图
from django.core.exceptions import ObjectDoesNotExist def detail_vote(request, id): voter_id = request.user.profile.id try: user_ticket_for_this_video = Ticket.objects.get(voter_id=voter_id, video_id=id) user_ticket_for_this_video.choice = request.POST['vote'] user_ticket_for_this_video.save() except ObjectDoesNotExist: new_ticket = Ticket(voter_id=voter_id, video_id=id, choice=request.POST['vote']) new_ticket.save() return redirect(to='detail', id=id)
解析:视图的逻辑是如果当前用户票已存在,则点击提交的状态进行修改保存;如果用户的票不存在,则根据提交结果新创建一张用户票。
2)在urls.py层增加投票视图
url(r'^detail/(?P3)在模板层增加投票结果跳转\d+)$', detail, name='detail'), url(r'^detail/vote/(?P \d+)$', detail_vote, name='vote'),
<form class="ui form" action="{% url 'vote' vid_info.id %}" method="post"> ... </form>
说明:action中内容即在点击投票结果的时候,会进行视图跳转。