mirror of
https://github.com/tencentmusic/cube-studio.git
synced 2024-11-21 01:16:33 +08:00
add no model api
This commit is contained in:
parent
363444bb49
commit
7048474932
@ -301,8 +301,8 @@ class MyappModelView(ModelView):
|
||||
search_widget = MySearchWidget
|
||||
help_url=''
|
||||
|
||||
pre_add_get = None
|
||||
pre_update_get = None
|
||||
pre_add_web = None
|
||||
pre_update_web = None
|
||||
post_list = None
|
||||
pre_show = None
|
||||
post_show = None
|
||||
@ -547,9 +547,9 @@ class MyappModelView(ModelView):
|
||||
@has_access
|
||||
def add(self):
|
||||
self.src_item_json = {}
|
||||
if request.method=='GET' and self.pre_add_get:
|
||||
if request.method=='GET' and self.pre_add_web:
|
||||
try:
|
||||
self.pre_add_get()
|
||||
self.pre_add_web()
|
||||
self.conv = GeneralModelConverter(self.datamodel)
|
||||
self.add_form = self.conv.create_form(
|
||||
self.label_columns,
|
||||
@ -643,9 +643,9 @@ class MyappModelView(ModelView):
|
||||
pk = self._deserialize_pk_if_composite(pk)
|
||||
self.src_item_object = self.datamodel.get(pk, self._base_filters)
|
||||
|
||||
if request.method=='GET' and self.pre_update_get and self.src_item_object:
|
||||
if request.method=='GET' and self.pre_update_web and self.src_item_object:
|
||||
try:
|
||||
self.pre_update_get(self.src_item_object)
|
||||
self.pre_update_web(self.src_item_object)
|
||||
self.conv = GeneralModelConverter(self.datamodel)
|
||||
# 重新更新,而不是只在初始化时更新
|
||||
self.edit_form = self.conv.create_form(
|
||||
|
@ -1,3 +1,4 @@
|
||||
import csv
|
||||
import functools
|
||||
import json
|
||||
import logging
|
||||
@ -11,7 +12,7 @@ from flask_appbuilder.actions import action
|
||||
from flask_babel import gettext as __
|
||||
from flask_appbuilder.actions import ActionItem
|
||||
from flask import jsonify, request
|
||||
from flask import flash
|
||||
from flask import flash,g
|
||||
from flask import current_app, make_response,send_file
|
||||
from flask.globals import session
|
||||
from flask_babel import lazy_gettext as _
|
||||
@ -64,8 +65,11 @@ from flask import (
|
||||
abort,
|
||||
)
|
||||
from flask_appbuilder.exceptions import FABException, InvalidOrderByColumnFABException
|
||||
from flask_appbuilder.api import ModelRestApi
|
||||
from myapp import app, db,cache
|
||||
from flask_appbuilder.security.decorators import permission_name, protect,has_access
|
||||
from flask_appbuilder.api import BaseModelApi,BaseApi,ModelRestApi
|
||||
from sqlalchemy.sql import sqltypes
|
||||
from myapp import app, appbuilder,db,event_logger,cache
|
||||
from myapp.models.favorite import Favorite
|
||||
conf = app.config
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -85,6 +89,8 @@ API_EXIST_ADD_ARGS_RIS_KEY='exist_add_args'
|
||||
API_IMPORT_DATA_RIS_KEY = 'import_data'
|
||||
API_DOWNLOAD_DATA_RIS_KEY = 'download_data'
|
||||
API_OPS_BUTTON_RIS_KEY = 'ops_link'
|
||||
API_ENABLE_FAVORITE_RIS_KEY = 'enable_favorite'
|
||||
|
||||
|
||||
def get_error_msg():
|
||||
if current_app.config.get("FAB_API_SHOW_STACKTRACE"):
|
||||
@ -227,6 +233,7 @@ def json_response(message,status,result):
|
||||
|
||||
|
||||
|
||||
import pysnooper
|
||||
# @pysnooper.snoop(depth=5)
|
||||
# 暴露url+视图函数。视图函数会被覆盖,暴露url也会被覆盖
|
||||
class MyappModelRestApi(ModelRestApi):
|
||||
@ -242,26 +249,68 @@ class MyappModelRestApi(ModelRestApi):
|
||||
src_item_json={} # 原始model对象的json
|
||||
check_edit_permission = None
|
||||
datamodel=None
|
||||
post_list=None
|
||||
pre_json_load=None
|
||||
|
||||
def pre_show(self,item):
|
||||
pass
|
||||
def pre_show_res(self,result):
|
||||
return result
|
||||
def pre_add(self, item):
|
||||
pass
|
||||
def post_add(self, item):
|
||||
pass
|
||||
def pre_add_req(self,req_json):
|
||||
return req_json
|
||||
def pre_add_res(self,result):
|
||||
return result
|
||||
|
||||
def pre_update_req(self,req_json):
|
||||
return req_json
|
||||
def pre_update_res(self,result):
|
||||
return result
|
||||
|
||||
def pre_update(self, item):
|
||||
pass
|
||||
def post_update(self, item):
|
||||
pass
|
||||
|
||||
def pre_list_req(self,req_json):
|
||||
return req_json
|
||||
def pre_list_res(self,result):
|
||||
return result
|
||||
|
||||
# 可以调整顺序
|
||||
def post_list(self, items):
|
||||
return items
|
||||
|
||||
def pre_delete(self, item):
|
||||
pass
|
||||
def post_delete(self, item):
|
||||
pass
|
||||
|
||||
# 添加和更新前info信息的查询,或者填写界面的查询
|
||||
def pre_add_web(self):
|
||||
pass
|
||||
def pre_update_web(self,item):
|
||||
pass
|
||||
|
||||
edit_form_extra_fields={}
|
||||
add_form_extra_fields = {}
|
||||
add_fieldsets = []
|
||||
edit_fieldsets=[]
|
||||
show_fieldsets = []
|
||||
pre_add_get=None
|
||||
|
||||
ops_link=[
|
||||
# {
|
||||
# "text": "git",
|
||||
# "url": "https://github.com/tencentmusic/cube-studio"
|
||||
# }
|
||||
]
|
||||
pre_update_get=None
|
||||
|
||||
help_url = None
|
||||
pre_show = None
|
||||
|
||||
default_filter={}
|
||||
actions = {}
|
||||
pre_list=None
|
||||
|
||||
user_permissions = {
|
||||
"add": True,
|
||||
"edit": True,
|
||||
@ -278,12 +327,10 @@ class MyappModelRestApi(ModelRestApi):
|
||||
cols_width={}
|
||||
import_data=False
|
||||
download_data=False
|
||||
enable_favorite=False
|
||||
pre_upload = None
|
||||
set_columns_related=None
|
||||
|
||||
# def pre_list(self,**kargs):
|
||||
# return
|
||||
|
||||
# @pysnooper.snoop()
|
||||
def csv_response(self,file_path,file_name=None):
|
||||
# 下载csv
|
||||
@ -452,6 +499,7 @@ class MyappModelRestApi(ModelRestApi):
|
||||
response[API_IMPORT_DATA_RIS_KEY] = self.import_data
|
||||
response[API_DOWNLOAD_DATA_RIS_KEY] = self.download_data
|
||||
response[API_OPS_BUTTON_RIS_KEY]=self.ops_link
|
||||
response[API_ENABLE_FAVORITE_RIS_KEY]=self.enable_favorite
|
||||
|
||||
# 重新渲染add界面
|
||||
# @pysnooper.snoop()
|
||||
@ -572,8 +620,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
|
||||
# @pysnooper.snoop(watch_explode=('edit_columns'))
|
||||
def merge_add_fieldsets_info(self, response, **kwargs):
|
||||
# if self.pre_add_get:
|
||||
# self.pre_add_get()
|
||||
# if self.pre_add_web:
|
||||
# self.pre_add_web()
|
||||
add_fieldsets=[]
|
||||
if self.add_fieldsets:
|
||||
for group in self.add_fieldsets:
|
||||
@ -836,7 +884,7 @@ class MyappModelRestApi(ModelRestApi):
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def response_error(self,code,message='error',status=1,result={}):
|
||||
def response_error(self, code, message='error', status=1, result={}):
|
||||
back_data = {
|
||||
'result': result,
|
||||
"status": status,
|
||||
@ -881,9 +929,9 @@ class MyappModelRestApi(ModelRestApi):
|
||||
id = _args.get(self.primary_key,'')
|
||||
if id:
|
||||
item = self.datamodel.get(id)
|
||||
if item and self.pre_update_get:
|
||||
if item and self.pre_update_web:
|
||||
try:
|
||||
self.pre_update_get(item)
|
||||
self.pre_update_web(item)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if item and self.check_item_permissions:
|
||||
@ -891,9 +939,9 @@ class MyappModelRestApi(ModelRestApi):
|
||||
self.check_item_permissions(item)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
elif self.pre_add_get:
|
||||
elif self.pre_add_web:
|
||||
try:
|
||||
self.pre_add_get()
|
||||
self.pre_add_web()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
@ -903,16 +951,17 @@ class MyappModelRestApi(ModelRestApi):
|
||||
|
||||
@expose("/<int:pk>", methods=["GET"])
|
||||
# @pysnooper.snoop(depth=4)
|
||||
def api_get(self, pk, **kwargs):
|
||||
if self.pre_show:
|
||||
src_item_object = self.datamodel.get(pk, self._base_filters)
|
||||
self.pre_show(src_item_object)
|
||||
def api_show(self, pk, **kwargs):
|
||||
|
||||
|
||||
# from flask_appbuilder.models.sqla.interface import SQLAInterface
|
||||
item = self.datamodel.get(pk, self._base_filters)
|
||||
if not item:
|
||||
return self.response_error(404, "Not found")
|
||||
|
||||
if self.pre_show:
|
||||
self.pre_show(item)
|
||||
|
||||
_response = dict()
|
||||
_args = kwargs.get("rison", {})
|
||||
if 'form_data' in request.args:
|
||||
@ -944,7 +993,7 @@ class MyappModelRestApi(ModelRestApi):
|
||||
_response['data'] = data # item.to_json()
|
||||
_response['data'][self.primary_key] = pk
|
||||
|
||||
back = self.pre_get(_response)
|
||||
back = self.pre_show_res(_response)
|
||||
back_data = {
|
||||
'result': back['data'] if back else _response['data'],
|
||||
"status": 0,
|
||||
@ -954,17 +1003,15 @@ class MyappModelRestApi(ModelRestApi):
|
||||
|
||||
|
||||
@expose("/", methods=["GET"])
|
||||
# @pysnooper.snoop(watch_explode=('_response','lst'))
|
||||
# @pysnooper.snoop(watch_explode=('_args','_filters'))
|
||||
def api_list(self, **kwargs):
|
||||
_response = dict()
|
||||
if self.pre_json_load:
|
||||
req_json = self.pre_json_load(request.json)
|
||||
else:
|
||||
try:
|
||||
req_json = request.json or {}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
req_json={}
|
||||
|
||||
try:
|
||||
req_json = request.json or {}
|
||||
except Exception as e:
|
||||
print(e)
|
||||
req_json={}
|
||||
|
||||
_args = req_json or {}
|
||||
_args.update(request.args)
|
||||
@ -972,9 +1019,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
if 'form_data' in request.args:
|
||||
_args.update(json.loads(request.args.get('form_data')))
|
||||
|
||||
if self.pre_list:
|
||||
self.pre_list(**_args)
|
||||
|
||||
if self.pre_list_req:
|
||||
_args = self.pre_list_req(_args)
|
||||
|
||||
# handle select columns
|
||||
select_cols = _args.get(API_SELECT_COLUMNS_RIS_KEY, [])
|
||||
@ -1005,6 +1051,23 @@ class MyappModelRestApi(ModelRestApi):
|
||||
page_index, page_size = self._handle_page_args(_args)
|
||||
# Make the query
|
||||
query_select_columns = _pruned_select_cols or self.list_columns
|
||||
|
||||
# @pysnooper.snoop()
|
||||
def get_favorite():
|
||||
all_rows = db.session.query(Favorite.row_id).filter(Favorite.model_name==self.datamodel.obj.__tablename__).filter(Favorite.user_id==g.user.id).all()
|
||||
all_rows_id = [int(row[0]) for row in all_rows]
|
||||
return all_rows_id
|
||||
|
||||
# 如果只查询收藏
|
||||
if _args.get('only_favorite',False):
|
||||
if self.primary_key not in self.search_columns:
|
||||
self.search_columns.append(self.primary_key)
|
||||
_args['filters']=[]
|
||||
self._filters.clear_filters()
|
||||
from flask_appbuilder.models.sqla.filters import FilterInFunction
|
||||
self._filters.add_filter(self.primary_key,FilterInFunction,get_favorite)
|
||||
joined_filters = self._filters.get_joined_filters(self._base_filters) # 将基础filter加入到过滤器中你那个
|
||||
|
||||
count, lst = self.datamodel.query(
|
||||
joined_filters,
|
||||
order_column,
|
||||
@ -1037,14 +1100,14 @@ class MyappModelRestApi(ModelRestApi):
|
||||
for index in range(len(lst)):
|
||||
|
||||
_response['data'][index][self.primary_key]= getattr(lst[index],self.primary_key)
|
||||
|
||||
result=_response
|
||||
try:
|
||||
self.pre_get_list(_response)
|
||||
result = self.pre_list_res(_response)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
back_data = {
|
||||
'result': _response,# _response['data']
|
||||
'result': result,
|
||||
"status": 0,
|
||||
'message': "success"
|
||||
}
|
||||
@ -1078,8 +1141,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
if not request.is_json:
|
||||
return self.response_error(400,message="Request is not JSON")
|
||||
try:
|
||||
if self.pre_json_load:
|
||||
json_data = self.pre_json_load(request.json)
|
||||
if self.pre_add_req:
|
||||
json_data = self.pre_add_req(request.json)
|
||||
else:
|
||||
json_data = request.json
|
||||
|
||||
@ -1120,7 +1183,6 @@ class MyappModelRestApi(ModelRestApi):
|
||||
item = self.datamodel.get(pk, self._base_filters)
|
||||
self.src_item_json = item.to_json()
|
||||
|
||||
# if self.check_redirect_list_url:
|
||||
try:
|
||||
if self.check_edit_permission:
|
||||
has_permission = self.check_edit_permission(item)
|
||||
@ -1137,8 +1199,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
if not item:
|
||||
return self.response_error(404,message='Not found')
|
||||
try:
|
||||
if self.pre_json_load:
|
||||
json_data = self.pre_json_load(request.json)
|
||||
if self.pre_update_req:
|
||||
json_data = self.pre_update_req(request.json)
|
||||
else:
|
||||
json_data = request.json
|
||||
data = self._merge_update_item(item, json_data)
|
||||
@ -1153,7 +1215,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
|
||||
try:
|
||||
self.datamodel.edit(item.data, raise_exception=True)
|
||||
self.post_update(item.data)
|
||||
if self.post_update:
|
||||
self.post_update(item.data)
|
||||
result = self.edit_model_schema.dump(
|
||||
item.data, many=False
|
||||
).data
|
||||
@ -1176,7 +1239,8 @@ class MyappModelRestApi(ModelRestApi):
|
||||
item = self.datamodel.get(pk, self._base_filters)
|
||||
if not item:
|
||||
return self.response_error(404,message='Not found')
|
||||
self.pre_delete(item)
|
||||
if self.pre_delete:
|
||||
self.pre_delete(item)
|
||||
try:
|
||||
self.datamodel.delete(item, raise_exception=True)
|
||||
self.post_delete(item)
|
||||
@ -1342,19 +1406,93 @@ class MyappModelRestApi(ModelRestApi):
|
||||
sql_engine = create_engine(uri)
|
||||
table_name = self.datamodel.obj.__tablename__
|
||||
# sql = 'select `%s` from %s' % ('`,`'.join(self.show_columns), table_name)
|
||||
file_path = '%s.csv' % table_name
|
||||
csv_file_path = os.path.abspath(file_path)
|
||||
if os.path.exists(csv_file_path):
|
||||
os.remove(csv_file_path)
|
||||
|
||||
_args = request.json or {}
|
||||
req_json = json.loads(request.args.get('form_data', "{}")) # 根据请求筛选下载数据,而不是全量下载
|
||||
_args.update(req_json)
|
||||
# 下载搜索出来的
|
||||
if _args and _args.get('filters',[]):
|
||||
joined_filters = self._handle_filters_args(_args)
|
||||
count, lst = self.datamodel.query(
|
||||
joined_filters,
|
||||
'',
|
||||
'',
|
||||
page=0,
|
||||
page_size='20000',
|
||||
select_columns=self.show_columns,
|
||||
)
|
||||
print(count,lst)
|
||||
if count>0:
|
||||
with(open(csv_file_path,'w',newline='',encoding="utf-8-sig")) as csvfile:
|
||||
csvwrite = csv.writer(csvfile,delimiter=',')
|
||||
csvwrite.writerow(self.show_columns)
|
||||
for item in lst:
|
||||
data = []
|
||||
for col in self.show_columns:
|
||||
data.append(getattr(item,col))
|
||||
csvwrite.writerow(data)
|
||||
csvfile.close()
|
||||
response = self.csv_response(csv_file_path, file_name=table_name)
|
||||
return response
|
||||
|
||||
# 下载全量
|
||||
sql = 'select * from %s' % (table_name)
|
||||
print(sql)
|
||||
results = pandas.read_sql_query(sql, sql_engine)
|
||||
results.to_csv(csv_file_path, index=False, sep=",",encoding='utf-8-sig') # index 是第几行的表示
|
||||
|
||||
file_path = '%s.csv' % table_name
|
||||
csv_file = os.path.abspath(file_path)
|
||||
if os.path.exists(csv_file):
|
||||
os.remove(csv_file)
|
||||
results.to_csv(csv_file, index=False, sep=",",encoding='utf-8-sig') # index 是第几行的表示
|
||||
response = self.csv_response(csv_file, file_name=table_name)
|
||||
response = self.csv_response(csv_file_path, file_name=table_name)
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@expose("/favorite/<pk>", methods=["POST",'DELETE'])
|
||||
# @pysnooper.snoop()
|
||||
def favorite(self,pk):
|
||||
if request.method=='POST':
|
||||
item = self.datamodel.get(pk, self._base_filters)
|
||||
if item:
|
||||
exist_favorite = db.session.query(Favorite).filter(Favorite.model_name==self.datamodel.obj.__tablename__).filter(Favorite.row_id==str(pk)).filter(Favorite.user_id==g.user.id).first()
|
||||
if not exist_favorite:
|
||||
favorite = Favorite(model_name=self.datamodel.obj.__tablename__,row_id=str(pk),user_id=g.user.id)
|
||||
db.session.add(favorite)
|
||||
db.session.commit()
|
||||
back_data = {
|
||||
'result': '',
|
||||
"status": 'success',
|
||||
'message': '收藏成功'
|
||||
}
|
||||
return self.response(200,**back_data)
|
||||
|
||||
else:
|
||||
back_data = {
|
||||
'result': '',
|
||||
"status": 'fail',
|
||||
'message': '目标不存在,或无权限查看'
|
||||
}
|
||||
return self.response(404, **back_data)
|
||||
elif request.method=='DELETE':
|
||||
exist_favorite = db.session.query(Favorite).filter(Favorite.model_name == self.datamodel.obj.__tablename__).filter(Favorite.row_id == str(pk)).filter(Favorite.user_id == g.user.id).first()
|
||||
if exist_favorite:
|
||||
db.session.delete(exist_favorite)
|
||||
db.session.commit()
|
||||
back_data = {
|
||||
'result': '',
|
||||
"status": 'success',
|
||||
'message': '取消收藏成功'
|
||||
}
|
||||
return self.response(200, **back_data)
|
||||
|
||||
# @expose("/git/<pk>", methods=["GET"])
|
||||
# def git(self,pk):
|
||||
# item = self.datamodel.get(pk, self._base_filters)
|
||||
# return response
|
||||
|
||||
|
||||
@action("muldelete", __("Delete"), __("Delete all Really?"), "fa-trash", single=False)
|
||||
# @pysnooper.snoop(watch_explode=('items'))
|
||||
def muldelete(self, items):
|
||||
|
1615
myapp/views/baseFormApi.py
Normal file
1615
myapp/views/baseFormApi.py
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user