Files

243 lines
8.4 KiB
Python
Raw Permalink Normal View History

2026-07-13 15:37:05 +08:00
# -*- coding: utf-8 -*-
# @Time : 2022/6/6 14:22
# @Author : 臧成龙
# @FileName: usual.py
# @Software: PyCharm
# -*- coding: utf-8 -*-
import os
from datetime import datetime
from urllib.parse import unquote
import openpyxl
from django.http import FileResponse
from django.shortcuts import get_object_or_404
from fuadmin.settings import BASE_DIR, STATIC_URL
from ninja import Schema
from openpyxl import load_workbook
from .fu_auth import data_permission
from .fu_ninja import FuFilters
from .fu_response import FuResponse
from .usual import get_user_info_from_token
class ImportSchema(Schema):
path: str
def create(request, data, model):
"""
创建新记录的函数
参数:
- request: 请求对象用于获取用户信息
- data: 创建记录的数据可以是字典或者支持dict()方法的对象
- model: Django ORM模型指定要创建的对象类型
返回值:
- 创建成功的对象查询集合
"""
if not isinstance(data, dict):
# 如果data不是字典类型则转换为字典
data = data.dict()
user_info = get_user_info_from_token(request)
# 从请求中提取用户信息,并添加到数据中作为创建人、修改者和所属部门信息
data['creator_id'] = user_info['id']
data['modifier'] = user_info['name']
data['belong_dept'] = user_info['dept']
# 使用提供的模型和数据创建新记录
query_set = model.objects.create(**data)
return query_set
def batch_create(request, data, model):
"""
批量创建模型实例
参数:
- request: HTTP请求对象用于获取用户信息
- data: 一个包含创建数据的列表每个元素可以是字典或者具有dict方法的对象
- model: Django模型类用于实例化和批量创建
返回值:
- query_set: 批量创建后的模型实例查询集
"""
user_info = get_user_info_from_token(request) # 从请求中获取用户信息
data_list = []
for item in data:
if not isinstance(item, dict):
item = item.dict() # 如果item不是字典则转换为字典
# 为每个创建的数据项添加默认的创建人、修改者和所属部门信息
item['creator_id'] = user_info['id']
item['modifier'] = user_info['name']
item['belong_dept'] = user_info['dept']
data_list.append(model(**item)) # 根据字典内容实例化模型对象并添加到列表中
query_set = model.objects.bulk_create(data_list) # 批量创建模型实例
return query_set
def delete(id, model):
"""
根据提供的ID和模型删除对象实例
参数:
- id: 要删除的对象的ID
- model: 对象所属的模型类
返回值:
- 无返回值
"""
# 根据ID和模型获取对象实例如果找不到则返回404错误页面
instance = get_object_or_404(model, id=id)
# 删除对象实例
instance.delete()
pass
def update(request, id, data, model):
"""
更新给定模型实例的数据
参数:
- request: HTTP请求对象用于获取用户信息
- id: 要更新的模型实例的ID
- data: 包含更新数据的实例应能转换为字典格式
- model: 要更新的模型类
返回值:
- 更新后的模型实例
"""
dict_data = data.dict() # 将data转换为字典格式
user_info = get_user_info_from_token(request) # 从请求中获取用户信息
# 为更新的数据添加修改者信息
dict_data['modifier'] = user_info['name']
instance = get_object_or_404(model, id=id) # 获取指定ID的模型实例
# 遍历字典,将更新的数据设置到模型实例上
for attr, value in dict_data.items():
setattr(instance, attr, value)
instance.save() # 保存更新
return instance # 返回更新后的实例
def retrieve(request, model, filters: FuFilters = FuFilters()):
"""
根据提供的过滤条件从数据库中检索模型实例
参数:
- request: HttpRequest对象用于获取请求信息
- model: Django模型类指定要检索的数据模型
- filters: FuFilters类的实例包含过滤条件默认为FuFilters()即无条件过滤
返回值:
- query_set: 一个Django QuerySet对象包含根据过滤条件检索到的模型实例
"""
# 根据请求和过滤条件应用数据权限控制
filters = data_permission(request, filters)
if filters is not None:
# 将filters中的空字符串值转换为None
for attr, value in filters.__dict__.items():
if getattr(filters, attr) == '':
setattr(filters, attr, None)
# 使用过滤条件查询模型实例
query_set = model.objects.filter(**filters.dict(exclude_none=True))
else:
# 如果没有有效的过滤条件,则返回所有模型实例
query_set = model.objects.all()
return query_set
def export_data(request, model, scheme, export_fields):
"""
导出数据为Excel文件
参数:
- request: HttpRequest对象表示客户端请求
- model: Django模型类指定要导出数据的模型
- scheme: 表示数据转换规则的对象用于将ORM对象转换为字典
- export_fields: 包含要导出的字段名的列表
返回值:
- FileResponse对象提供下载Excel文件
"""
title_dict = {}
# 根据export_fields列表获取字段的显示名称
for field in export_fields:
field_obj = getattr(model, field).field
title_dict[field] = field_obj.help_text
qs = retrieve(request, model)
list_data = []
# 将查询集中的每一项转换为指定格式的字典
for qs_item in qs:
qs_item = scheme.from_orm(qs_item)
dict_data = {}
for item, value in title_dict.items():
dict_data[value] = getattr(qs_item, item)
list_data.append(dict_data)
# 创建并初始化Excel工作簿
wb = openpyxl.Workbook()
ws = wb.active
# 向Excel中写入数据
for index, data in enumerate(list_data):
if index == 0:
# 写入表头
ws.append(list(data.keys()))
ws.append(list(data.values()))
# 生成唯一的文件名并设置文件路径
file_name = datetime.now().strftime('%Y%m%d%H%M%S%f') + '.xlsx'
current_ymd = datetime.now().strftime('%Y%m%d')
file_path = os.path.join(STATIC_URL, current_ymd)
file_url = os.path.join(file_path, file_name)
# 确保导出文件的目录存在
if not os.path.exists(file_path):
os.makedirs(file_path)
# 保存Excel文件到指定路径
wb.save(file_url)
# 返回供下载的文件响应
return FileResponse(open(file_url, "rb"), as_attachment=True)
def import_data(request, model, scheme, data, import_fields):
"""
导入数据到指定模型
参数:
- request: HttpRequest对象表示客户端请求
- model: Django模型类数据将被导入到这个模型
- scheme: 一个函数用于根据给定的数据字典创建模型实例
- data: 包含要导入文件信息的对象比如上传的Excel文件
- import_fields: 一个列表指定模型中需要导入的字段名
返回值:
- FuResponse对象包含导入结果的消息
"""
title_dict = {} # 字段名与Excel列对应的字典
for field in import_fields:
field_obj = getattr(model, field).field
title_dict[field_obj.help_text] = field_obj.column
# 文件路径处理
file_path = str(BASE_DIR) + unquote(data.path)
# 加载Excel工作簿
wb = load_workbook(file_path)
ws = wb.active # 获取活动工作表
title_value = []
for index_row, row in enumerate(ws.values):
if index_row == 0:
title_value = row # 读取Excel表头
else:
dict_data = {} # 存储每一行数据转换后的字典
for index, cell in enumerate(row):
title_cell = title_value[index]
value = title_dict.get(title_cell) # 根据表头查找对应字段
if value is not None:
dict_data[value] = cell
print(dict_data) # 打印处理后的数据,用于调试
data = scheme(**dict_data) # 根据处理后的字典创建模型实例
create(request, data, model) # 在数据库中创建模型实例
return FuResponse(msg='导入成功') # 返回成功消息