ioe/inventory/utils/view_utils.py
2025-04-27 14:50:32 +08:00

196 lines
5.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""视图工具函数,用于减少视图中的重复代码"""
from django.shortcuts import get_object_or_404
from django.contrib import messages
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from inventory.models import OperationLog
def log_operation(user, operation_type, details, related_object=None):
"""
记录操作日志的通用方法
Args:
user: 执行操作的用户
operation_type: 操作类型
details: 操作详情
related_object: 相关对象
"""
log_entry = OperationLog(
operator=user,
operation_type=operation_type,
details=details
)
if related_object:
content_type = ContentType.objects.get_for_model(related_object)
log_entry.related_content_type = content_type
log_entry.related_object_id = related_object.id
log_entry.save()
return log_entry
def handle_form_submission(request, form_class, template_name, success_url,
success_message, instance=None, extra_context=None,
pre_save_callback=None, post_save_callback=None):
"""
处理表单提交的通用方法
Args:
request: HTTP请求
form_class: 表单类
template_name: 模板名称
success_url: 成功后重定向的URL
success_message: 成功消息
instance: 编辑时的实例对象
extra_context: 额外的上下文数据
pre_save_callback: 保存前的回调函数
post_save_callback: 保存后的回调函数
Returns:
HttpResponse: 响应对象
"""
from django.shortcuts import render, redirect
context = extra_context or {}
if request.method == 'POST':
form = form_class(request.POST, request.FILES, instance=instance) if instance else form_class(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit=False)
# 执行保存前回调
if pre_save_callback:
pre_save_callback(obj, form)
obj.save()
form.save_m2m() # 保存多对多关系
# 执行保存后回调
if post_save_callback:
post_save_callback(obj, form)
messages.success(request, success_message)
return redirect(success_url)
else:
form = form_class(instance=instance) if instance else form_class()
context['form'] = form
return render(request, template_name, context)
def get_object_with_check(model_class, object_id, user=None, permission=None):
"""
获取对象并检查权限的通用方法
Args:
model_class: 模型类
object_id: 对象ID
user: 用户对象
permission: 需要检查的权限
Returns:
Model: 获取的对象
"""
obj = get_object_or_404(model_class, id=object_id)
# 如果需要检查权限
if user and permission and not user.has_perm(permission):
from django.core.exceptions import PermissionDenied
raise PermissionDenied()
return obj
def search_objects(queryset, search_term, search_fields):
"""
通用搜索方法
Args:
queryset: 初始查询集
search_term: 搜索词
search_fields: 搜索字段列表
Returns:
QuerySet: 过滤后的查询集
"""
if not search_term:
return queryset
q_objects = Q()
for field in search_fields:
q_objects |= Q(**{f"{field}__icontains": search_term})
return queryset.filter(q_objects)
def require_ajax(view_func):
"""
装饰器确保视图只能通过AJAX调用
Args:
view_func: 被装饰的视图函数
Returns:
包装后的视图函数
"""
from django.http import HttpResponseBadRequest
from functools import wraps
@wraps(view_func)
def wrapped(request, *args, **kwargs):
if not request.headers.get('x-requested-with') == 'XMLHttpRequest':
return HttpResponseBadRequest('该接口只接受AJAX请求')
return view_func(request, *args, **kwargs)
return wrapped
def require_post(view_func):
"""
装饰器确保视图只能通过POST方法调用
Args:
view_func: 被装饰的视图函数
Returns:
包装后的视图函数
"""
from django.http import HttpResponseNotAllowed
from functools import wraps
@wraps(view_func)
def wrapped(request, *args, **kwargs):
if request.method != 'POST':
return HttpResponseNotAllowed(['POST'], '该接口只接受POST请求')
return view_func(request, *args, **kwargs)
return wrapped
def get_referer_url(request, default_url='/'):
"""
获取请求的Referer URL如果不存在则返回默认URL
Args:
request: HTTP请求对象
default_url: 默认的返回URL
Returns:
str: Referer URL或默认URL
"""
referer = request.META.get('HTTP_REFERER')
return referer if referer else default_url
def get_int_param(request, param_name, default=None):
"""
从请求中获取整数参数
Args:
request: HTTP请求对象
param_name: 参数名称
default: 默认值
Returns:
int/None: 转换后的整数值或默认值
"""
value = request.GET.get(param_name) or request.POST.get(param_name)
if value:
try:
return int(value)
except (ValueError, TypeError):
pass
return default