基于Django的携程网Top热门景点数据可视化分析

news2024/11/18 17:51:26

前言: 

今天给大家分享一个基于Django的携程网Top热门景点数据可视化分析项目,以下是该项目大大概内容

项目名称:基于Python(django)的携程Top热门景点数据可视化分析

涉及技术:Python,Django,Mysql,Web前端~

项目实现功能:用户登录注册,个人信息编辑,数据总览以及收藏,对爬取的数据进行可视化图标的展示等~

现在简单来分析一下这个小项目吧:

项目分析以及展示:

1:登录注册

这个功能基本上是每一个同学做设计网站的过程中必不可少的步骤啦,其实这个就是一个Form表单的Post提交验证,注册时获取输入框上的文本后,然后 models.objects.create(字段1=值1,字段2-值2......)就可以啦,登陆时只需获取输入框的内容验证其账号和密码是否存在于Mysql数据库即可,有的话则正常进入首页(下一页),没有的话课适当弹出提示信息

代码:

def login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    if request.method == 'POST':
        name = request.POST.get('name')
        password = request.POST.get('password')
        if User.objects.filter(username=name, password=password):
            user=User.objects.get(username=name, password=password)
            username=request.session['username'] = {'username':user.username,'avatar':str(user.avatar)}
            return redirect('index')
        else:
            msg = '信息错误!'
            return render(request, 'login.html', {"msg": msg})

# 02用户注册
def register(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        password = request.POST.get('password')
        phone = request.POST.get('phone')
        email = request.POST.get('email')
        avatar = request.FILES.get('avatar')
        stu = User.objects.filter(username=name)
        if stu:
            msg = '用户已存在!'
            return render(request, 'register.html', {"msg": msg})
        else:
            User.objects.create(username=name,password=password,phone=phone,email=email,avatar=avatar)
            msg = "注册成功!"
            return render(request, 'login.html', {"msg": msg})
    if request.method == 'GET':
        return render(request,'register.html')

2:个人信息编辑

只需使用数据库ORM的filter()字段为用户名等于我们登录时的名称即可,这里咱们知道获取我们登陆时的所昵称或者别的信息的,这里可以使用Session缓存 的方法来获取,具体怎么操作,我的上一篇博客已经介绍过啦,然后我们就顺利拿到我们用户的对象啦,然后正常映射到前端即可啦,修改个人信息也是Post方法,然后获取新的输入内容后,只需yourmodel.字段=获取的新数据 即可实现数据库原本内容的覆盖修改:

代码:

def selfInfo(request):
    username = request.session.get("username").get('username')
    useravatar = request.session.get("username").get('avatar')
    userInfo=User.objects.get(username=username)
    context={'username':username,'useravatar':useravatar,'userInfo':userInfo}
    return render(request,'selfInfo.html',context)

 

3:数据总览

这个内容就纯粹获取全部数据遍历展示啦:

4:数据收藏

这个是有一点难度的,实现点击收藏景点就可以把数据库传递显示在收藏页面(技术本质时,点击收藏按钮将该数据保存存储一个新的数据库里),我们根据ID来获取当前点击的对象,然后创建新的数据库,这里的数据库表的建立就会显得尤其重要啦,这里需要用到ForeignKey外键关联的细节啦,

这里比如我们收藏的数据存在数据库History里,然后该项目另外还有两个数据库(景点Places,用户User),我们看一下代码就知道啦:代码:

class History(models.Model):
    id = models.AutoField('id',primary_key=True)
    place = models.ForeignKey(Places,on_delete=models.CASCADE)
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    count = models.IntegerField("点击次数",default=1)
    class Meta:
        db_table = "history"
    class Meta:
        db_table = 'History'
        verbose_name_plural = '收藏管理'

关联景点表使用户我们展示景点表中的每一个字段的具体信息,关联用户是因为我们使用缓存在辨别每一位不同的用户他们收藏的数据肯定也不一样,另外我们按照一个景点点击的次数多少来从在前端页面上到下排列。

5:可视化图表

可视化图表我是使用Echarts来呈现的,当然这个可视化展示的工具有很多大家可以自己决定使用哪一款(pyecharts,matplotlib,mapbr...),做过可视化的同学都知道,echarts他的可视化的数据信息有多种数据结构的比如单列表,列表里面嵌套字典,字典里面嵌套字典等,所以我们只需要将数据库里的数据拿出来处理成我们需要的样子即可啦,由于我这这个项目里的数据图表也不算少,所以我就只拿有两个图表来讲解举例:

比如下面的这种可视化的图,这个没有怎么设计到图表的内容:

效果图如下:

代码:

def index(request):
    users = User.objects.all()
    data = {}
    for u in users:
        if data.get(str(u.time),-1) == -1:
            data[str(u.time)] = 1
        else:
            data[str(u.time)] += 1
    result = []
    for k,v in data.items():
        result.append({
            'name':k,
            'value':v
        })
    timeFormat = time.localtime()
    year = timeFormat.tm_year
    month = timeFormat.tm_mon
    day = timeFormat.tm_mday
    monthList = ["January","February","March","April","May","June","July","August","September","October","November","December"]
    username = request.session.get("username").get('username')
    useravatar = request.session.get("username").get('avatar')
    newuserlist = User.objects.all()
    places=Places.objects.all()
    # 数据总量
    placeslength=len(places)
    # 用户总量
    userlength=len(User.objects.all())
    # 火热城市 h(例:)为北京,上海,深圳
    hotcitylist=[]
    hotcity=places.order_by('-hot')[0:3]

    for h in hotcity:
        hotcitylist.append(h.city)
    strres=''
    for h in hotcitylist:
        strres= strres+h+"~"
    hotcitylist=strres[:-1]
    # 最高级别
    """levellist=[]
    for p in places:
        levellist.append(p.level[0])
    levellist=levellist.sort(reverse=True)
    levellistres=levellist[0] # 为最高等级5A"""
    levellistres='5A'
    # 评论量最高
    totalaccountres=places.order_by('-totalaccount')[0]
    totalaccountlistres=totalaccountres.totalaccount
    # 评分最高
    scoreres=places.order_by('-score')[0]
    scorelistres=scoreres.score
    goodaccountrate=places.order_by('-goodaccountrate')[0]
    goodaccountrate=goodaccountrate.goodaccountrate
    context={'userTime':result,'year':year,'month':monthList[month-1],'day':day,'useravatar':useravatar,'username':username,'newuserlist':newuserlist,
             'placeslength':placeslength,'userlength':userlength,'hotcitylist':hotcitylist,'levellistres':levellistres,'totalaccountlistres':totalaccountlistres,
             'scorelistres':scorelistres,'places':places,'goodaccountrate':goodaccountrate}
    return render(request,'index.html',context)

获取数量:

# 数据总量
placeslength=len(places)
# 用户总量
userlength=len(User.objects.all())

Top最高的数据可以直接orderby(-字段)[0]即可,获取该字段的最高的一条数据然后获取该数据的该字段值,火热城市同理,按照hot热度排列取前3个对象数据,然后取出该3条数据的该字段值,然后可以利用字符串拼接的方法做城市之间的~连接展示。

接下来看这个图片:

这个图片是Echarts可视化工具的常见的饼图:他Echarts源数据是这样的(如下图:)

在data里面,是一个列表里面嵌套字典的形式,所以我们针对我们这个项目需要处理处理成[{北京:2},{上海:3},{杭州:5}......]既表达每个城市有多少景点,所有我们使用如下代码:

places = Places.objects.all();dict1={};result1=[];dict2={};result2=[];
for i in places:
    if dict1.get(i.city,-1)==-1:
        dict1[i.city]=1
    else:
        dict1[i.city]+=1
for k,v in dict1.items():
    result1.append({
        'value': v,
        "name":k
    })

这段代码首先从数据库中获取所有的 Places 对象,然后使用两个字典 dict1 和 dict2 和两个列表 result1 和 result2 进行处理。

  1. places = Places.objects.all();:通过 Places.objects.all() 获取数据库中所有的 Places 对象,并将其存储在 places 变量中。

  2. dict1 = {}; result1 = []; dict2 = {}; result2 = [];:初始化了两个空字典 dict1 和 dict2,以及两个空列表 result1 和 result2

  3. for i in places::遍历 places 中的每个 Places 对象。

  4. if dict1.get(i.city, -1) == -1::检查 dict1 中是否存在键为 i.city 的条目,如果不存在,返回 -1;存在则返回对应的值。

    • 如果返回值为 -1,说明 dict1 中没有 i.city 这个键,这时将 i.city 作为键,初始化其值为 1

    • 如果返回值不为 -1,说明 dict1 中已经存在 i.city 这个键,这时将对应的值加 1

  5. for k, v in dict1.items()::遍历 dict1 中的每一对键值对。

  6. result1.append({'value': v, "name": k}):将每个城市的数量 v 和城市名称 k 作为键值对添加到 result1 列表中,形成字典的列表结构。

综上所述,该代码的功能是统计数据库中每个城市出现的次数,并将结果以字典列表的形式存储在 result1 中。

其他类推(直接上效果图):

最后需要本项目的同学可以私信我或者下面加我微信~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1492243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么有了HTTP协议,还要有WebSocket协议?

文章目录 使HTTP不断轮询长轮询WebSocket是什么?怎么建立WebSocket连接WebSocket抓包WebSocket的消息格式WebSocket的使用场景总结 平时我们打开网页,比如购物网站某宝。都是点一下列表商品,跳转一下网页就到了商品详情。 从HTTP协议的角度来…

[C语言]——scanf和printf介绍

目录 一.printf 1.基本用法 2.占位符 3.占位符列举 4.输出格式 4.1限定宽度 4.2总是显示正负号 4.3限定小数位数 4.4输出部分字符串 二.scanf 1.基本用法 2.scanf的返回值 3.占位符 4.赋值忽略符 一.printf 1.基本用法 printf() 的作⽤是将参数⽂本输出到屏幕。…

winui开发笔记(五)应用程序图标

应用程序图标、发布者、显示名称大部分都在package.appxmanifest清单文件中,可以正常打开,也可以使用xml文本编辑器打开。 以下是一个正常的应用程序中所有的与图标相关的图片: 但是设置之后会有一圈白,包括在电脑最下边一行&…

chrome插件extensions获取所有窗口tab页和windows页

获取windows页:https://developer.chrome.com/docs/extensions/reference/api/windows?hlzh-cn 获取所有tabs页:https://developer.chrome.com/docs/extensions/reference/api/tabs?hlzh-cnchrome.tabshttps://developer.chrome.com/docs/extensions/…

MYSQL C++链接接口编程

使用MYSQL 提供的C接口来访问数据库,官网比较零碎,又不想全部精读一下,百度CSDN都是乱七八糟的,大部分不可用 官网教程地址 https://dev.mysql.com/doc/connector-cpp/1.1/en/connector-cpp-examples-connecting.html 网上之所以乱七八糟,主要是MYSQL提供了3个接口两个包,使用…

打家劫舍(java版)

📑前言 本文主要是【动态规划】——打家劫舍(java版)的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一…

QT对象树 | 内存泄漏

使用 Qt 框架构建 GUI 界面的程序 //widget.cpp #include "widget.h" #include "ui_widget.h" #include <QLabel>Widget::Widget(QWidget *parent) //这里的parent的意思是父级指针: QWidget(parent) //调用父类的构造函数, ui(new Ui::Widget) …

外包干了3个月,技术倒退明显

先说情况&#xff0c;大专毕业&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近6年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&#xf…

主备DNS服务器搭建并验证

目录 1. 配置静态网络 2. 配置主备DNS 2.1 DNS备服务器&#xff08;第二个虚拟机&#xff09; 2.2 两个虚拟机操作 2.3 备用服务器&#xff08;第二个虚拟机&#xff09;执行 2.4 两个虚拟机都添加DNS: 3. 验证 3.1 主DNS服务验证: 3.2 备用DNS服务器验证&am…

基于Springboot的足球俱乐部管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球俱乐部管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍: 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff…

C语言指针的初步认识--学习笔记(3)

1. 字符指针变量 在C语言中&#xff0c;字符串通常被视为字符数组&#xff0c;但它们可以有不同的表示方式。字符指针变量存储的是字符串的地址。这意味着&#xff0c;当你有一个字符串时&#xff0c;你可以通过改变字符指针的值来改变这个字符串&#xff0c;因为你实际上改变的…

22.欧拉方法、刚体模拟、流体模拟

一、一个粒子的模拟 规定一个物体在某一个时刻的速度和位置&#xff0c;如何解出某个时间之后它会出现在哪里 下图要求模拟一个粒子在速度场中要如何运动 速度场中&#xff0c;在任何一个位置&#xff0c;我们都有它的速度 写出来相当于是常微分方程 我们知道速度&#xff0c;…

find函数-秒了道题

秒了 笑死 还是规规矩矩做吧 string类的find()函数用于在字符串中查找字符或子串&#xff0c;返回第一个匹配的位置。 class Solution { public:int strStr(string haystack, string needle) {return haystack.find(needle);} };

基于灰狼算法GWO的城市三维无人机路径规划(复杂地形三维航迹路径规划)

摘要 本文提出了一种利用灰狼算法GWO来解决城市环境下无人机三维路径规划问题的方法。这种方法将复杂的无人机航迹规划任务转化为一个优化问题&#xff0c;然后运用灰狼算法GWO来解决这个优化问题。灰狼算法GWO是一种模拟灰狼种群捕猎行为的优化算法&#xff0c;它具备强大的全…

【TEE】内存完整性保护

Hash Functions&Merkle Tree 对读操作进行完整性检查&#xff0c;通过在加载的块上重新计算一个哈希&#xff0c;然后根据片外地址将得到的哈希与片上哈希比较。 缺点&#xff1a;不可承受的片上存储开销&#xff0c;并假设128位哈希和512位cache line&#xff0c;其开销为…

C++基于多设计模式下的同步异步日志系统day6

C基于多设计模式下的同步&异步日志系统day6 &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C基于多设计模式下的同步&异步日志系统 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&am…

JPA generator 生成实体类

1、配置生成实体类 选中表后点击右键 2、 Generate POJOs.groovy 配置 import com.intellij.database.model.DasTable import com.intellij.database.model.ObjectKind import com.intellij.database.util.Case import com.intellij.database.util.DasUtilimport java.text.S…

K次取反后最大化的数组和 加油站 分发糖果 柠檬水找零

1005.K次取反后最大化的数组和 力扣题目链接(opens new window) 给定一个整数数组 A&#xff0c;我们只能用以下方法修改该数组&#xff1a;我们选择某个索引 i 并将 A[i] 替换为 -A[i]&#xff0c;然后总共重复这个过程 K 次。&#xff08;我们可以多次选择同一个索引 i。&a…

类与对象(二)--类的六个默认成员函数超详细讲解

目录 1.类的默认六个成员函数✒️ 2.构造函数 2.1构造函数的概念✒️ 2.2构造函数的特性✒️ 3.析构函数 3.1析构函数的概念✒️ 3.2析构函数的特征✒️ 4.拷贝构造函数 4.1拷贝构造函数的概念✒️ 4.2拷贝构造函数的特征✒️ 4.3思考❓ 4.4深拷贝和浅拷贝⭐️…

嵊州吃喝玩乐篇

1. 豆腐馒头 胖大姐豆腐馒头&#xff08;推荐&#xff09; 地址: 嵊州市越秀路96-98号 高德地图搜 “胖大姐黄泽豆腐馒头” 黄泽豆腐馒头 地址&#xff1a;嵊州市越秀路111号 高德地图搜 “嵊州市玉英豆腐馒头店” 2. 烧烤 老张烧烤&#xff08;推荐&#xff09; 地址&a…