IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 用djaogo开发一个投票系统 -> 正文阅读

[Python知识库]用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"),

结尾

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

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-14 13:59:04  更:2021-08-14 14:01:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 10:20:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码