python(二)基于flask返回json数据接口:目录结构、程序架构、flask、flask-sqlalchemy部署安装

上篇介绍了如何部署安装开发环境。从这篇开始详细描述一步步开发过程。

python的web框架flask是个很轻量级的,安装方便,可是官方网站能提供的文档,不是很详细。我从头开始详细描述我本次的开发过程。

数据库采用的Mysql,ORM框架采用的flask-sqlalchemy,flask-sqlalchemy是对于sqlalchemy框架的封装。更好的跟flask框架融合。之前开发公司项目一直使用的是.net,在.NET里面有DataTable类,相当于SQL查出来的结果集跟对象之间并没有直接联系。后面我会用专门的篇幅总结flask-sqlalchemy的专门知识。

首先要知道python项目包的概念可以理解为目录,每个python目录都一个_init_.py文件,这个具体怎么个流程我这就不细研究了。

1)先看我这个项目的目录结构。

    这个文件目录参考了以前公司开发项目的结构。

2)开发项目涉及到

      web框架:flask

      ORM框架:flask-sqlalchemy

      Log插件:logzero

      EXCEL处理插件:xlrd

     查看本机安装的python插件情况,可以在cmd下运行pip freeze.

   

3)安装各个插件,如果在linux下很可能已经安装了python2.7版本。在安装python3以后,安装其他插件时需要使用pip3命令。

在cmd下执行

pip install -upgrade pip                          (更新pip程序)

pip install flask                                      (安装flask框架)

pip install flask-sqlalchemy                   (安装flask-sqlalchemy框架)

pip install pymysql                                (安装python连接数据库插件)

pip install logzero                                   (安装logzero日志插件)

pip install xlrd                                       (安装xlrd插件,读取EXCEL插件)

 

4)先编辑runserver.py

from mock import app

if __name__ == '__main__':
    #JSON的汉字是否以ASCII码输出,选择false
    app.config['JSON_AS_ASCII']=False

    app.run(debug=True)

5)再编辑mock下的_init_.py

# -*- coding: utf-8 -*-

from flask import Flask,redirect,url_for
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS

#通过FLASK生成app
app=Flask(__name__)

#这个根据情况而定,CORS(app)解决跨域访问问题,这块没有仔细研究
CORS(app)

#flask的配置通过mock.setting来读取
app.config.from_object('mock.setting')   
 
#通过app创建数据库访问对象db
db = SQLAlchemy(app)

#加载model类
import mock.model.mockmodel

#加载视图层
import mock.controller.SearchController
import mock.controller.Uploadexcel

6)Model层具体如下,这里大概说明一下业务关系。

songs表示歌曲,对应songs表。

artists表示歌手表,对应artists表。

一首歌可以被多个歌手唱,一个歌手也可以唱多首歌,所以歌曲和歌手之间的关系是多对多。

多对多的关系保存在artist_songs表中。因为artist_songs表会在后面配置多对多关系时使用,所以放在最前面。

还有一个类lyric_copies,是歌词版权,表示一首歌可能会有多种版权分配方式,所以是一对多的关系。

这里先呈列代码,后面详细篇幅介绍flask-sqlalchemy的使用。

from mock import db

artist_songs = db.Table('artist_songs',
    db.Column('song_id', db.Integer, db.ForeignKey('songs.id')),
    db.Column('artist_id', db.Integer, db.ForeignKey('artists.id'))
    )  

class songs(db.Model):
    __tablename__ = 'songs'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(255), nullable=True)
    lyrics = db.Column(db.Text(), nullable=True)
    created_at = db.Column(db.DateTime, nullable=False)
    artists=db.relationship('artists', secondary=artist_songs,backref = db.backref('artists'),lazy="select")
    lyric_copies=db.relationship('lyric_copies',backref='songs',lazy='select')
  
     def jsonstr(self):
        artist=[]
        if self.artists is not None and len(self.artists)!=0:
            for art in self.artists:
                artist.append(art.name)
        
        lyricarr=[]
        if self.lyric_copies is not None and len(self.lyric_copies)!=0:
            for lyr in self.lyric_copies:
                lyricarr.append(lyr.jsonstr())
                
        jsondata = { 
            'ID': self.id, 
            'title': self.title,
            'artist': artist,
            'lyric':self.lyrics,
            'copyrights':{
                'lyric':lyricarr
            }
        }
        return jsondata

class artists(db.Model):
    __tablename__ = 'artists'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(255), nullable=True)
    gender = db.Column(db.Integer, nullable=True)
    location = db.Column(db.String(255), nullable=True)
    created_at = db.Column(db.DateTime, nullable=False)
    updated_at = db.Column(db.DateTime, nullable=False)

class lyric_copies(db.Model):
    __tablename__ = 'lyric_copies'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(255), nullable=True)
    created_at = db.Column(db.DateTime, nullable=False)
    updated_at = db.Column(db.DateTime, nullable=False)
    song_id = db.Column(db.Integer, db.ForeignKey('songs.id'),nullable=False)

7)Controller层的处理查询需求的searchcontroller.py

from mock import app
from flask import jsonify,request
from mock.Utility.RequestHelper import RequestHelper
from mock.Utility.logger import logger
from mock.BSL.SongsBSL import SongsBSL

@app.route('/search', methods=['GET', 'POST'])
def search():
    try:
        keyvalue=RequestHelper.getValue(request, 'keyvalue')
        pagesize=RequestHelper.getValue(request,'pagesize')
        pageindex=RequestHelper.getValue(request,'pageindex')
        resultdata=[]
        if pagesize =='':
            pagesize=20
        if pageindex =='':
            pageindex=1
        songsbsl=SongsBSL()
        songlist=songsbsl.QuerySongListByORCondition(keyvalue)
        songitems=songlist.paginate(int(pageindex), int(pagesize),False)
        if songitems is not None and len(songitems.items)!=0:
            for ss in songitems.items:
                result.append(ss.jsonstr())
        return jsonify(resultdata)
    except Exception as e:
        logger.error(str(e))
        return jsonify(resultdata)

8)业务逻辑层的SongsBSL.py

from mock import db
from mock.model.mockmodel import songs, artists, artist_songs
from sqlalchemy.sql.expression import or_, and_

class SongsBSL():
    def QuerySongListByORCondition(self,keyvalue):
        return songs.query.join(artist_songs).join(artists).filter(or_(songs.title.like('%'+keyvalue+'%') , artists.name.like('%'+keyvalue+'%')))
    

9)工具类中的RequestHelper.py

class RequestHelper:
    @staticmethod
    def getValue(request,parm):
        if request.method == 'POST':
            result=request.form.get(parm)
        else:
            result=request.args.get(parm)
        if result is None:
            return ''
        else:
            return result.encode('utf-8').decode('utf-8')

在这里我先把基本的主要代码先罗列上来,具体技术细节后面的篇幅单独拿出来讲。

 

 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值