赞
踩
基于python 的股市行情查询系统开发(三)
pip install django ''' 使用清华源加快下载速度'''
选择一个文件目录,在目录下输入:django-admin startproject 项目名
django-admin startproject stock
文件目录如下:
在cmd项目根目录下输入后面可以加ip:端口号
出现以下信息代表项目已经运行成功:
浏览器输入127.0.0.1:8000(默认端口):
这样我们的项目的基本框架就已经搭建好了。
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
成功!可以看到数据已经实时地展现在首页上了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。