基于python 的股票行情查询系统开发(三)————使用vue+django框架将数据显示
基于python 的股市行情查询系统开发(三)一、django框架构建项目1)下载djangopip install django ''' 使用清华源加快下载速度'''2)构建项目选择一个文件目录,在目录下输入:django-admin startproject项目名django-admin startproject stock文件目录如下:在cmd项目根目录下输入后面可以加ip:端口号出现以下信
基于python 的股市行情查询系统开发(三)
一、django框架构建项目
1)下载django
pip install django ''' 使用清华源加快下载速度'''
2)构建项目
选择一个文件目录,在目录下输入:django-admin startproject 项目名
django-admin startproject stock
文件目录如下:
在cmd项目根目录下输入后面可以加ip:端口号
出现以下信息代表项目已经运行成功:
浏览器输入127.0.0.1:8000(默认端口):
这样我们的项目的基本框架就已经搭建好了。
3)新建model模型
stock目录下输入:
python .\manage.py startapp stocklist
在生成的文件目录中的model文件中对model对象的数据类型进行定义:
from django.db import models
# Create your models here.
class Stock(models.Model):
stockcode = models.CharField(max_length=20) '''股票代码'''
stockname = models.CharField(max_length=20) '''股票名称'''
构建后别忘了在stock目录下的setting.py文件的INSTALLED_APPS中加入stocklist。
......
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'stocklist'
]
......
之后输入如下,用以在数据库中建立stocklist表用于获取之前存储在csv文件中的沪深A股的股票代码和名称:
我使用的是默认的数据库sqlite3,这里vscode的插件可以对数据库进行可视化,在market中搜索sqlite即可:
可以看到数据库中的表已经构建成功了。
好了,之后我们就可以把csv数据导入数据库了。
在stock目录下新建accessdata文件。
# /stock/accessdata.py
from stocklist.models import Stock
import csv
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def write_stock_list(self):
with open('D:\\股票数据\\stocklist.csv','r',encoding='utf-8') as f:
reader = csv.reader(f)
csv_list = []
for row in reader:
if tuple([row[0]]) not in csv_list:
obj = Stock( stockcode= row[1],stockname = row[0])
csv_list.append(obj)
Stock.objects.bulk_create(csv_list)
return HttpResponse("OK")
在url.py中加入该方法请求:
# /stock/urls.py
from . import accessdata
from django.conf.urls import url
urlpatterns = [
url('write/',accessdata.write_stock_list),
]
再次运行一下:
查看数据库:
OK,准备工作完成。
二、获取实时数据
如何获取到实时的股票数据呢?非常简单,东方财富网就可以。目前的链接为http://push2.eastmoney.com/api/qt/stock/get?fields=f43,f44,f45,f46,f47,f48,f49,f50,f51,f52,f57,f58,f71,f116,f117,f60,f162,f163,f164,f167,f168,f170,f173&secid=股票代码
需要注意的是股票代码前要加1. 代表上海 0.代表深圳。
这里使用grequests来加快请求的速度:获取1700多支的数据大约要5秒钟,
@csrf_exempt
def get_allcode(request): #获取所有的实时股票信息
QuerySet = Stock.objects.all()
list =[]
dictlist = []
stockdict = {}
for stock in QuerySet:
list.append(get_url+"1."+stock.stockcode)
'''url=http://push2.eastmoney.com/api/qt/stock/get?fields=f43,f44,f45,f46,f47,f48,f49,f50,f51,f52,f57,f58,f71,f116,f117,f60,f162,f163,f164,f167,f168,f170,f173&secid='''
tasks = [grequests.get(u) for u in list]
datalist = grequests.map(tasks,size= 2000)
for data in datalist:
dict ={'data2':json.loads(data.text)}
dictlist.append(accessformat(dict))
for i in range(len(dictlist)):
stockdict[i] = dictlist[i]
return HttpResponse(json.dumps(stockdict))
注意不要忘记在url.py加入此路径进行匹配:
urlpatterns = [
...
url('get_allcode/',accessdata.get_allcode),
...
]
跑一下看看:
其实数据已经获取到了,但还是unicode编码,我们需要将其进行转化一下。
另:使用grequests是会报如下异常:
但是不影响程序运行,有没有同样使用的小伙伴告诉一下怎么解决啊啊
将数据进行处理一下:
def accessformat(LIST):
stocknowdata = LIST['data2']['data']
if(stocknowdata ==None):
return 'None'
listnow = list(stocknowdata.values())
listnew = [listnow[10],listnow[11],listnow[0],listnow[1],
listnow[21],listnow[2],listnow[3],listnow[12],
listnow[8],listnow[9],listnow[4],listnow[5],
listnow[6],listnow[7],listnow[13],listnow[14],
listnow[15],listnow[16],listnow[17],listnow[18],
listnow[12],listnow[20],listnow[22]]
#print(listnew)
label = ['股票代码','股票名称','最新价','最高价','涨跌幅','最低价','开盘价','昨收',
'涨停','跌停','成交量(手)','成交额','外盘','量比','均价',
'总市值','流通市值','市盈(动)','静市盈率','滚动市盈率','市净率',
'换手率','ROE']
#df = pd.DataFrame(columns=label)
b=dict(zip(label,listnew))
return b
打印看看:
可以看到数据其实是已经处理好的,就是传到前端时又转为unicode了。
这时候我们就需要vue来将数据显示一下了。
三、将数据实时显示在前端页面
下载npm后,进行vue脚手架的搭建:
npm install -g vue-cli
之后进行一路选择默认后进入项目目录
npm install
安装完成后,输入
npm run serve
启动成功后,我们在index.html加入前端美化代码:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
<title>django vue stock</title>
</head>
<body>
<div id="app"></div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.4.1/dist/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
</body>
</html>
src目录下的vue文件名修改为Container.vue
<template>
<div class="container">
<nav class="navbar navbar-expand-lg navbar-light bg-warning">
<a class="navbar-brand" href="#">Menu</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">A Stock <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item active">
<a class="nav-link" href="#">find other</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input v-model="stockcode" class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="button" @click="getnewstock()">Search</button>
</form>
</div>
</nav>
<div class="row">
<div class="col-md-12">
<!-- 右边是博客内容表格部分 -->
<table class="table table-bordered table-hover">
<thead>
<th class="text-center">stockcode</th>
<th class="text-center">stockname</th>
<th class="text-center">stocknow</th>
<th class="text-center">stockhigh</th>
<th class="text-center">stocklow</th>
<th class='text-center'>stockopen</th>
<th class='text-center'>stockchange</th>
<th class='text-center'>stockyesday</th>
<th class='text-center'>stockamount</th>
</thead>
<tbody>
<!-- <tr>-->
<tr v-for='stock in stocks' :key='stock.id' >
<td>{{stock.股票代码}}</td>
<td>{{stock.股票名称}}</td>
<td>{{stock.最新价}}</td>
<td>{{stock.最高价}}</td>
<td>{{stock.最低价}}</td>
<td>{{stock.开盘价}}</td>
<td>{{stock.涨跌幅}}</td>
<td>{{stock.昨收}}</td>
<td>{{stock.成交额}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import Qs from 'qs';
export default {
name: 'Container',
props: {
},
data(){
return{
//base_url:'http://172.18.204.60:8000/api/stock/',
stocks:null,
url:'',
title:'',
content:'',
stockcode:'',
}
},
methods:{
// getAll(){
// axios.get('http://localhost:8000/api/stock/')
// .then(res=>{
// this.stocks = res.data;
// this.url = '';
// this.title = ''
// this.content = ''
// });
getnewstock(){
if(this.stockcode=='')
{
axios({
headers:{'Content-Type':'application/x-www-form-urlencoded'},
method:'get',
url :'http://localhost:8000/get_allcode/'
}).then(res=>{
this.stocks = res.data
console.log(res.data)
})
}
else
{
let data = {stockcode:this.stockcode}
axios({
headers:{'Content-Type':'application/x-www-form-urlencoded'},
method:'post',
url : 'http://localhost:8000/access_stock_code/',
data :Qs.stringify(data)
}).then(res=>{
this.getnewdata(res.data)
console.log(res.data)
})
}
},
getnewdata(stockcode){
axios({
headers:{'Content-Type':'application/x-www-form-urlencoded'},
method:'get',
url :'http://push2.eastmoney.com/api/qt/stock/get?fields=f43,f44,f45,f46,f47,f48,f49,f50,f51,f52,f57,f58,f71,f116,f117,f60,f162,f163,f164,f167,f168,f170,f173&secid='+stockcode,
}).then(res=>{
this.accessdata(res.data)
console.log(res.data)
})
},
accessdata(data){
let data1= {data2 :data}
axios({
method:'post',
url :'http://localhost:8000/accessdata/',
data :JSON.stringify(data1)
}).then(res=>{
console.log(res.data)
this.stocks = {stock:res.data}
created(){
// this.getAll();
this.getnewstock();
}
}
}
</script>
<style scoped>
</style>
App.vue文件修改如下:
<template>
<div id="app">
<Container />
</div>
</template>
<script>
import Container from './components/Container.vue'
export default {
name: 'App',
components: {
Container
}
}
</script>
main.js:
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
这里还有一个问题,我们使用的是前后端分离的项目模式,所以前端向后端请求会存在跨域问题,因此,在django中的settings.py中INSTALLED_APPS加入django-cores,MIDDLEWARE 中加入’corsheaders.middleware.CorsMiddleware’,‘corsheaders.middleware.CorsPostCsrfMiddleware’,再加入CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL =True即可
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'stocklist',
'corsheaders', #加入#
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'stock.urls'
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL =True
ok,浏览器输入localhost:8080/
点击search
成功!可以看到数据已经实时地展现在首页上了
更多推荐
所有评论(0)