用djaogo开发一个投票系统

投票系统

创建基本模型

投票系统,我们必须要建立的两个基本模型就是投票人(用户,下文我统一用“用户”)和被投票人,话不多说,先上代码:

1:被投票人的基本模型

class Person(models.Model):
    # 姓名
    name = models.CharField(max_length=30)
    # 票数
    ballot = models.FloatField(default=0, max_length=30, null=False)
    # 性别
    sex = models.CharField(max_length=30)
    # 班级
    Class = models.CharField(max_length=30)
    # 专业
    major = models.CharField(max_length=30)
    # 年级
    grade = models.CharField(max_length=30)
    # 突出事迹
    story = models.TextField()
    # 照片
    img_url = models.CharField(max_length=150, null=True)

    def __str__(self):
        return f"{self.name} - {self.Class} - {self.ballot} - {self.sex}"

2:用户

用户名和密码我们可以直接可以继承User类,其余字段自己定义

class userform(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    nickname = models.CharField(blank=True, max_length=50)
    phonenumber = models.CharField(blank=True, max_length=20)
    banji = models.CharField(blank=True, max_length=20)
    xuehao = models.CharField(blank=True, max_length=20)
    count = models.FloatField(default=0, blank=True, max_length=50)
    # 头像
    img_url = models.CharField(max_length=150, null=True)
    #给模型赋予元数据
    class Meta:
        verbose_name_plural = "userform"

或许作为刚入手django的新手来说,做这样的投票系统会有以下想法:在views中定义一个vote方法,获取当前用户和被投票人,检查用户的count字段是否小于5(投票限制),若是,则被投票人的ballot字段加一,保存,这样虽然也可以实现简单的邮票限制,不过方法很死,不容易进行拓展。
代码如下,代码中那几个int,str的转换是因为我一开始定义的字段类型是CharField

def vote(request, id):
    # 投票
    obj = models.Person.objects.get(id=id)
    user = request.user
    user_count = user.userform.count
    user_count = int(user_count)
    if user_count < 5:
        user.userform.count = int(user.userform.count) + 1
        user.userform.count = str(user.userform.count)
        user.userform.save()
        piao = int(obj.ballot) + 1
        obj.ballot = piao
        obj.save()
        url = reverse('showall')
        return HttpResponse(f'<script>alert("投票成功");location.href="' + url + '";</script>')
    else:
        url = reverse('showall')
        return HttpResponse(f'<script>alert("每人只能投五票!");location.href="' + url + '";</script>')

接下来我们继续,淘汰上述方法,继续淦。

我们可以在models里面再建一个模型,建一个用户和被投票人的中间模型,来记录每一次投票记录

class VotesRecord(models.Model):
    voted_person = models.ForeignKey("Person", on_delete=models.DO_NOTHING)
    voting_person = models.ForeignKey("userform", on_delete=models.DO_NOTHING)
    vote_datetime = models.DateTimeField()

    def __str__(self):
        return f"{self.voted_person.name} - {self.voting_person.nickname} - {self.vote_datetime}"

模型方法的构建

在该中间模型中,我们额外定义了投票时间这个字段,这样我们就可以对投票限制进行扩展,比如一天可以投5票,哪个时间段有多少限制,可以自由发挥。
定义好上述3个模型我们就可以写我们的投票方法,不过,如果将全部的代码都写在views中并不是一件好事,我们最好在模型中先写好模型方法,这样只用在views中写我们的逻辑判断,然后执行不同的方法即可。Let’s go
首先,在userform即我们的用户模型中添加vote方法

class userform(models.Model):
	###字段省略,看上文
	def vote(self, voted_person: Person):
        new_record = VotesRecord()
        new_record.voted_person = voted_person
        new_record.voting_person = self
        new_record.vote_datetime = datetime.datetime.now()
        new_record.save()
        self.count += 1
        voted_person.ballot += 1
        self.save()
        voted_person.save()
        return new_record

这样,我们就完成了投票方法的书写。

接下来我们写投票限制条件的方法。

在userform即我们的用户模型中添加vote_data方法,用来检查当前用户的投票数

class userform(models.Model):
	###字段省略,看上文
	def vote_data(self, today=False):
        if today:
            current_datetime = datetime.datetime.now()
            return self.votesrecord_set.filter(voting_person=self,
                                               vote_datetime__year=current_datetime.year,
                                               vote_datetime__month=current_datetime.month,
                                               vote_datetime__day=current_datetime.day)
        else:
            return self.votesrecord_set.filter(voting_person=self)

这样,我们在调用该方法的时候,只需要令today=True 即可获取到当前用户所有的投票纪录,然后用count()方法即可知道当前用户今日偷的总票数。代码中用到的votesrecord_set如果不懂可以去看看django官方文档对于中间模型的介绍。应该在多对多关系里面有所介绍
多对多关系

通过以上,我们就可以实现一天之内一个用户最多可以投多少票,这样的方法比博客开头的方法显然更优,而且可以在django的后台查看投票纪录
django的admin后台
投票纪录也可以在数据库中查看。
做到这里其实已经不错了,但是我们可以继续稍微拓展一下,限制每位用户每天不能给同一用户投超过3票,如果可以理解上面的方法,那么这个功能添加起来也不是什么难事。

我们在views中用以下方法得到当前用户今日一共给被投票人的投票纪录

vote_records2: QuerySet = user.votesrecord_set.filter(voted_person = voted_person,vote_datetime__year=current_datetime.year,
                                               vote_datetime__month=current_datetime.month,
                                               vote_datetime__day=current_datetime.day)

然后通过count()方法得到数量

##views中书写逻辑

def vote(request, id):
    # 投票  
    voted_person = models.Person.objects.get(id=id)
    user = request.user.userform
    current_datetime = datetime.datetime.now()
    vote_records2: QuerySet = user.votesrecord_set.filter(voted_person = voted_person,vote_datetime__year=current_datetime.year,
                                               vote_datetime__month=current_datetime.month,
                                               vote_datetime__day=current_datetime.day)
    vote_records: QuerySet = user.vote_data(today=True)
    user_count2 = vote_records2.count()
    user_count = vote_records.count()
    if user_count2 >= 3 :
        url = reverse('showall')
        return HttpResponse(f'<script>alert("您每天最多给同一个人投三票");location.href="' + url + '";</script>')
    if user_count < 5:
        new_record = user.vote(voted_person)
        url = reverse('showall')
        return HttpResponse(f'<script>alert("投票成功");location.href="' + url + '";</script>')
    else:
        url = reverse('showall')
        return HttpResponse(f'<script>alert("您每天最多投5票");location.href="' + url + '";</script>')

解释一下那个id
在这里插入图片描述
这是我的前端页面
下面是部分代码

<th>
          {% if request.user.is_superuser %}
                  <a href="{% url 'deleteperson' i.id %}">删除</a>
                 <a href="{% url 'changeperson' %}?id={{ i.id }}">修改</a>
            {% endif %}
                        <a href="{% url 'vote' i.id %}">投票</a>
              </th>```

点击投票,页面会传来你要投的对象的Id.

还有,url里面也要加上/int:id,表示接受一个int类型参数

path('vote/<int:id>', views.vote, name="vote"),

结尾

到这里有关投票的相关已经介绍完了,通过写这个小系统也学到了不少东西,当然,并没有把整个系统完全进行介绍,还有用户的注册,登录,提名,排行榜这些东西,不过通过投票这几个模型的构建,其他功能也不是很麻烦了,有兴趣的小伙伴可以在此基础上继续做哦!如果接下来有时间,可以把剩余的内容也进行分享。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值