django练手( 二十五):上传图标的页面仅授权人员可以访问
一、知识准备:
- django的permission_required()函数,这个函数可以作为装饰器使用。
- 这个函数有两个参数。第一个参数是”鉴权字符串“,即需要检验的权限对象。字符串的写法是:app.add/change/delete/view+模型名。add/change/delete/view 分别对应增/改/删/查。第二个参数是可选参数,分别对应鉴权失败后不同的处理方式。下面分别介绍这三个参数。
- 三个参数选项分别是, 不填/鉴权失败跳转的路由/raise_exception=True。不填:即鉴权失败后什么也不做。这个参数一般配合@login_required()装饰器使用,鉴权失败后,会自动跳转到登录页面。第二个选项,鉴权失败后跳转的路由,即给一个路由,鉴权失败后跳转到这个地址。第三个选项raise_exception=True,鉴权失败后前台跳转到”403 Forbidden“页面,后台报”django.core.exceptions.PermissionDenied“异常。
- 我的代码中,使用的是第一种,什么都不填,配合@login_required装饰器使用。
二、代码实现:
- 引入permission_required()函数。代码如下:
from django.contrib.auth.decorators import permission_required
- 在上传图标,删除图标两个方法前使用装饰器@permission_required,本节以上传图标为例:
# 图标上传
@login_required
# @permission_required('app.add_avatar',raise_exception=True)
@permission_required('app.add_avatar', )
def avatar_upload(request):
if request.method == 'GET':
# 获取所有的用户图标数据
avatars = Avatar.objects.filter(is_active=True).order_by('-id')
# 注意:Paginator查询集能处理的queryset必须是有序的
paginator = Paginator(avatars, 3)
# 获浏览器传递的取页码数
page_num = request.GET.get('page_num', '')
# 如果page_num非空且page_num字符串只有数字构成。方法isnumeric() 检测字符串是否只由数字组成。这种方法是只针对unicode对象。
if page_num is not None and page_num.isnumeric():
page_num = int(page_num)
else:
page_num = 1
if page_num not in paginator.page_range:
page_num = 1
avatars = paginator.page(page_num)
#
page_range = paginator.page_range
page_range = new_page_range(page_range, page_num)
return render(request, 'app/avatar.html', {"avatars": avatars, "page_range": page_range})
if request.method == "POST":
# 1、判断文件路径是否存在,如果不存在,生成文件路径。
image_folder_path = os.path.join(settings.MEDIA_ROOT, 'image', 'avatar') # 文件路径
image_folder_path_exists = os.path.exists(image_folder_path) # 判断文件路径是否存在
# 如果不存在,则生成文件路径
if not image_folder_path_exists:
os.makedirs(image_folder_path)
# 获取所有上传的图标
file_list = request.FILES.getlist('avatar_upload')
if file_list:
for file in file_list:
# 1、把文件名替换成整个系统唯一的文件名。
name = uuid_name(file.name)
# 2、获取文件中文名
title = os.path.splitext(file.name)[0]
# 3、文件存储的位置。
file_path = image_folder_path + '\\' + name
# 4、把文件写入硬盘
with open(file_path, 'wb', ) as f:
for part in file.chunks():
f.write(part) # 内容块写入文件
f.flush() # 清除内存
# 5、生成存储在数据库里的路径。
database_path = 'uploads/image/avatar/' + name
# 6、把文件信息写入数据库
avatar = Avatar()
avatar.title = title
avatar.img_url = database_path
avatar.save()
return JsonResponse({"status": True, })
三、效果如下图
本节代码已上传至gitee.com。仓库地址是:https://gitee.com/yanfenglucky/bokeyuan