-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ba31f78
Showing
22 changed files
with
553 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
import uuid | ||
|
||
import os | ||
from flask import request, session | ||
from flask_restful import Api, Resource, marshal_with, fields, marshal, reqparse | ||
from sqlalchemy import or_ | ||
from werkzeug.datastructures import FileStorage | ||
|
||
import settings | ||
from models import User, Image, Music | ||
from dao import query, queryAll, add, delete, queryById, deleteById | ||
|
||
api = Api() | ||
|
||
|
||
def init_api(app): | ||
api.init_app(app) | ||
|
||
|
||
class UserApi(Resource): # 声明User资源 | ||
def get(self): | ||
# 读取请求参数中的key | ||
key = request.args.get('key') | ||
if key: | ||
result = {'state': 'fail', | ||
'msg': '查无数据'} | ||
# 搜索用户信息 key = id/name/phone | ||
qs = query(User).filter(or_(User.id == key, | ||
User.name == key, | ||
User.phone == key)) | ||
if qs.count(): | ||
result['state'] = 'ok' | ||
result['msg'] = '查询成功' | ||
result['data'] = qs.first().json | ||
|
||
return result | ||
|
||
# 从数据库查询所有用户 | ||
users = queryAll(User) | ||
|
||
return {'state': 'ok', | ||
'data': [user.json for user in users]} | ||
|
||
def post(self): | ||
# 从上传的form对象中取出name和phone | ||
name = request.form.get('name') | ||
phone = request.form.get('phone') | ||
|
||
print(name, phone) | ||
# 数据存入到数据库 | ||
user = User() | ||
user.name = name | ||
user.phone = phone | ||
|
||
add(user) # 添加到数据库 | ||
|
||
return {"state": "ok", | ||
"msg": '添加 {} 用户成功!'.format(name)} | ||
|
||
def delete(self): | ||
id = request.args.get('id') # id -> str | ||
# user = queryById(User, id) # 是否考虑 id 不存在的情况 | ||
# delete(user) | ||
|
||
flag = deleteById(User, id) | ||
|
||
return {'state': 'ok', | ||
'flag': flag, | ||
'msg': '删除 {} 成功'.format(id)} | ||
|
||
def put(self): | ||
id = request.form.get('id') | ||
user = queryById(User, id) | ||
user.name = request.form.get('name') | ||
user.phone = request.form.get('phone') | ||
|
||
add(user) | ||
|
||
return {'state': 'ok', | ||
'msg': user.name + '更新成功! '} | ||
|
||
|
||
class ImageApi(Resource): | ||
|
||
# 设置图片Image对象输出的字段 | ||
img_fields = {"id": fields.Integer, | ||
"name": fields.String, | ||
# "img_url": fields.String(attribute='url'), | ||
"url": fields.String, | ||
"size": fields.Integer(default=0)} | ||
get_out_fields = { | ||
'state': fields.String(default='ok'), | ||
'data': fields.Nested(img_fields), | ||
"size": fields.Integer(default=1) | ||
} | ||
|
||
# # 输入的定制 | ||
# parser = reqparse.RequestParser() | ||
# parser.add_argument('id', | ||
# type=int, # 参数类型 | ||
# required=True, # 是否必要 | ||
# help='请提供id参数') # 必须的参数不存在 | ||
|
||
# @marshal_with(get_out_fields) | ||
def get(self): | ||
# self.parser.parse_args() # 解析参数,如果我们的参数不满足,直接返回下一步 | ||
|
||
id = request.args.get('id') | ||
if id: | ||
img = query(Image).filter(Image.id == id).first() | ||
|
||
# 将对象转成输出的字段格式(json格式) | ||
return marshal(img, self.img_fields) | ||
else: | ||
# 查询所有Image | ||
images = queryAll(Image) | ||
data = {'data': images, | ||
"size": len(images)} | ||
|
||
# 向session中存放用户名 | ||
session['login_name'] = 'ming' | ||
return marshal(data, self.get_out_fields) | ||
|
||
# return {'state': 'ok', | ||
# 'data': [{'name': 'miss', 'url': '/static/images/c.jpg'}, | ||
# {'name': 'null', 'url': '/static/images/va.jpg'}]} | ||
|
||
parser = reqparse.RequestParser() | ||
parser.add_argument('name', required=True, help='必须提供图片名称参数') | ||
parser.add_argument('url', required=True, help='必须提供已上传图片的路径') | ||
|
||
def post(self): | ||
args = self.parser.parse_args() | ||
|
||
# 保存数据 | ||
img = Image() | ||
img.name = args.get('name') | ||
img.url = args.get('url') | ||
|
||
add(img) # 添加到数据库中 | ||
|
||
return {'msg': '添加图片成功!'} | ||
|
||
|
||
class MusicApi(Resource): | ||
# 创建request参数的解析器 | ||
parser = reqparse.RequestParser() | ||
|
||
# 向参数解析器中添加请求参数说明 | ||
parser.add_argument('key', dest='name', type=str, required=True, help='必须提供name搜索的关键字') | ||
parser.add_argument('id', type=int, help='请确定id的参数是否为int类型?') | ||
parser.add_argument('tag', action='append', required=True, help='至少提供一个Tag标签') | ||
parser.add_argument('session', location='cookies', required=True, help='cookie中不存在session') | ||
|
||
# 定制输出 | ||
music_fields = { | ||
'id': fields.Integer, | ||
'name': fields.String, | ||
'singer': fields.String, | ||
'url': fields.String(attribute='mp3_url') | ||
} | ||
|
||
out_fields = { | ||
'state': fields.String(default='ok'), | ||
'msg': fields.String(default='查询成功'), | ||
'data': fields.Nested(music_fields) | ||
} | ||
|
||
@marshal_with(out_fields) | ||
def get(self): | ||
# 按name 搜索 | ||
# 通过request参数解析器,开始解析请求参数 | ||
# 如果请求参数不能满足条件,则直接返回参数相关的help说明 | ||
args = self.parser.parse_args() | ||
|
||
# 从args中读取name的请求参数的值 | ||
name = args.get('name') | ||
tags = args.get('tag') | ||
|
||
# 从args中读取session(cookies的session) | ||
session = args.get('session') | ||
print('session->>', session) | ||
|
||
musics = query(Music).filter(Music.name.like('%{}%'.format(name))) | ||
if musics.count(): | ||
return {'data': musics.all()} | ||
|
||
return {'msg': '{} 资源已失效,标签:{}'.format(name, tags)} | ||
|
||
|
||
class UploadApi(Resource): | ||
# 定制输入的参数 | ||
parser = reqparse.RequestParser() | ||
parser.add_argument("img", | ||
type=FileStorage, | ||
location='files', | ||
required=True, | ||
help='必须提供一个名为img的File表单参数') | ||
|
||
def post(self): | ||
# 验证 请求参数是否满足条件 | ||
args = self.parser.parse_args() | ||
|
||
# 保存上传的文件 | ||
uFile: FileStorage = args.get('img') | ||
print('上传的文件名:', uFile.filename) | ||
|
||
newFileName = str(uuid.uuid4()).replace('-', '') | ||
newFileName += "." + uFile.filename.split('.')[-1] | ||
|
||
uFile.save(os.path.join(settings.MEDIA_DIR, newFileName)) | ||
|
||
return {'msg': '上传成功!', | ||
'path': '/static/uploads/{}'.format(newFileName)} | ||
|
||
|
||
# 将资源添加到api对象中,并声明uri | ||
# ------------------------------- | ||
api.add_resource(UserApi, '/user/') | ||
api.add_resource(ImageApi, '/images/') | ||
api.add_resource(MusicApi, '/music/') | ||
api.add_resource(UploadApi, '/upload/') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from flask_sqlalchemy import SQLAlchemy, BaseQuery | ||
|
||
db = SQLAlchemy() | ||
|
||
|
||
def init_db(app): | ||
db.init_app(app) | ||
|
||
|
||
def query(cls) -> BaseQuery: # 通过 -> 声明函数返回的类型 | ||
return db.session.query(cls) | ||
|
||
|
||
def queryAll(cls): | ||
return query(cls).all() | ||
|
||
|
||
def queryById(cls, id): # 根据id查找 数据 | ||
return query(cls).get(int(id)) | ||
|
||
|
||
def add(obj): # 添加和更新 | ||
db.session.add(obj) | ||
db.session.commit() | ||
|
||
|
||
def delete(obj): # 删除 | ||
db.session.delete(obj) | ||
db.session.commit() | ||
|
||
|
||
def deleteById(cls, id): | ||
try: | ||
obj = queryById(cls, id) | ||
delete(obj) | ||
return True | ||
except: | ||
pass | ||
return False |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from flask import Flask | ||
from apis import init_api | ||
import settings | ||
from dao import init_db | ||
|
||
app = Flask(__name__) | ||
|
||
# 配置app | ||
app.config.from_object(settings.Config) | ||
|
||
# 初始化api | ||
init_api(app) | ||
|
||
# 初始化db或dao | ||
init_db(app) | ||
|
||
if __name__ == '__main__': | ||
app.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# coding: utf-8 | ||
from sqlalchemy import Column, ForeignKey, Integer, String | ||
from sqlalchemy.orm import relationship | ||
from sqlalchemy.ext.declarative import declarative_base | ||
|
||
|
||
Base = declarative_base() | ||
metadata = Base.metadata | ||
|
||
|
||
class Collect(Base): | ||
__tablename__ = 'collect' | ||
|
||
id = Column(Integer, primary_key=True) | ||
user_id = Column(ForeignKey('user.id'), index=True) | ||
img_id = Column(ForeignKey('image.id'), index=True) | ||
|
||
img = relationship('Image', primaryjoin='Collect.img_id == Image.id', backref='collects') | ||
user = relationship('User', primaryjoin='Collect.user_id == User.id', backref='collects') | ||
|
||
|
||
class Image(Base): | ||
__tablename__ = 'image' | ||
|
||
id = Column(Integer, primary_key=True) | ||
name = Column(String(50)) | ||
url = Column(String(200)) | ||
|
||
|
||
class Music(Base): | ||
__tablename__ = 'music' | ||
|
||
id = Column(Integer, primary_key=True) | ||
name = Column(String(50)) | ||
singer = Column(String(20)) | ||
brand = Column(String(20)) | ||
mp3_url = Column(String(100)) | ||
user_id = Column(ForeignKey('user.id'), index=True) | ||
|
||
user = relationship('User', primaryjoin='Music.user_id == User.id', backref='musics') | ||
|
||
|
||
class User(Base): | ||
__tablename__ = 'user' | ||
|
||
id = Column(Integer, primary_key=True) | ||
name = Column(String(20)) | ||
phone = Column(String(12)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import os | ||
|
||
# 设置上传文件存放的位置 | ||
BASE_DIR = os.path.dirname(os.path.abspath(__name__)) | ||
|
||
STATIC_DIR = os.path.join(BASE_DIR, 'static') | ||
MEDIA_DIR = os.path.join(STATIC_DIR, 'uploads') | ||
|
||
|
||
class Config(): | ||
ENV = 'development' | ||
DEBUG = True | ||
|
||
# 数据库配置 | ||
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:[email protected]:3306/users' | ||
SQLALCHEMY_TRACK_MODIFICATIONS = False | ||
|
||
# 设置session相关的参数 | ||
SECRET_KEY = 'MELAN' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>图库</title> | ||
</head> | ||
<body> | ||
<h3>所有图库</h3> | ||
<hr> | ||
<ul id="imageUL"></ul> | ||
<script src="/static/js/jquery.min.js"></script> | ||
<script> | ||
$(function () { | ||
$.getJSON('/images/', function (data) { | ||
alert(data.state); | ||
for (var i = 0; i < data.data.length; i++) { | ||
var li = "<li><img src='" + data.data[i].url + "'></li>"; | ||
$('#imageUL').append(li) | ||
|
||
} | ||
}) | ||
}) | ||
</script> | ||
</body> | ||
</html> |
Oops, something went wrong.