python装饰器Django类视图装饰

本文详细介绍了Python装饰器的四种类型,包括简易装饰器、无参数有返回值装饰器、有参数有返回值装饰器以及类装饰器,并展示了如何在Django类视图中使用装饰器,包括为全部请求方法和特定请求方法添加装饰器的两种方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、python装饰器

1、简易装饰器(无参数,无返回值)
def decorator01(func):
    def neweat():
        print('饭前先洗手 (原函数before执行....)')
        func()
        print('饭后百步走 (原函数after执行.....)')
    return neweat

@decorator01
def eat():   # 原函数
    print('吃饭咯.. (原函数running....)')

# 调用原函数
eat()
print('被装饰后的原函数名', eat.__name__)
2、装饰器(无参数,有返回值)
from functools import wraps

def decorator02(func):
    @wraps(func)                          # 保持原函数名称不变
    def neweat():
        print('饭前先洗手    before执行....')
        ret = func()
        print('饭后百步走    after执行.....')
        return ret
    return neweat

@decorator02
def eat():            # 原函数
    print('吃饭咯..    原函数running....')
    return '好饱'

# 调用原函数
result = eat()
print('原函数的返回值为:', result)
print(eat.__name__)
3、装饰器(有参数,有返回值)
from functools import wraps

def decorator03(a):
    def decorator(func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            b = a + '--装饰器处理后--'
            ret = func(b)
            return ret
        return wrapped_function
    return decorator

@decorator03(a='参数')
def myfunc1(b):
    resp = b + '--原函数处理--'
    return resp

ret = myfunc1()
print(ret)
4、类装饰器
from functools import wraps

class logit(object):
    def __init__(self, logfile='out.log'):
        self.logfile = logfile

    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            log_string = func.__name__ + " was called"
            print(log_string)
            # 打开logfile并写入
            with open(self.logfile, 'a') as opened_file:
                # 现在将日志打到指定的文件
                opened_file.write(log_string + '\n')
            # 现在,发送一个通知
            self.notify()
            return func(*args, **kwargs)

        return wrapped_function

    def notify(self):
        # logit只打日志,不做别的
        pass

# 装饰
@logit()
def myfunc1():
    pass

二、Django类视图使用装饰器

为类视图添加装饰器,可以使用两种方法

def my_decorator(func):
    def wrapper(request, *args, **kwargs):
        print('自定义装饰器被调用了')
        print('请求路径%s' % request.path)
        return func(request, *args, **kwargs)
    return wrapper

class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

在Django类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器。
method_decorator装饰器使用 name 参数指明被装饰的方法

1、为全部请求方法添加装饰器
from django.utils.decorators import method_decorator

@method_decorator(my_decorator, name='dispatch')
class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    def post(self, request):
        print('post方法')
        return HttpResponse('ok')
2、为特定请求方法添加装饰器
2.1 特定方法添加装饰(方式一)
from django.utils.decorators import method_decorator

@method_decorator(my_decorator, name='get')
class DemoView(View):
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

如果需要为类视图的多个方法添加装饰器,但又不是所有的方法(为所有方法添加装饰器参考上面例子),可以直接在需要添加装饰器的方法上使用method_decorator,如下所示

2.2 特定方法添加装饰(方式二)
from django.utils.decorators import method_decorator

class DemoView(View):
    @method_decorator(my_decorator)  # 为get方法添加了装饰器
    def get(self, request):
        print('get方法')
        return HttpResponse('ok')

    @method_decorator(my_decorator)  # 为post方法添加了装饰器
    def post(self, request):
        print('post方法')
        return HttpResponse('ok')

    def put(self, request):  # 没有为put方法添加装饰器
        print('put方法')
        return HttpResponse('ok')

END

<think>嗯,用户想了解Python装饰器在登录验证中的应用。首先,我需要回忆装饰器的基本概念。装饰器是一个函数,它可以修改其他函数的行为,而不需要改变它们的代码。这对于添加诸如验证、日志记录或权限检查之类的功能非常有用。 接下来,我应该考虑如何将装饰器用于登录验证。通常,某些页面或功能需要用户登录后才能访问。使用装饰器,可以在需要验证的函数前添加一个装饰器,自动检查用户是否登录。 可能需要先定义一个装饰器函数,比如叫做login_required。这个装饰器会检查用户的会话中是否有登录信息,比如是否存在user_id。如果未登录,就重定向到登录页面;如果已登录,则正常执行原函数。 然后,我需要举例说明如何在实际的Web框架中使用这个装饰器,比如Flask或Django。例如,在Flask中,可以通过检查session对象中的用户信息来判断登录状态。装饰器内部会定义一个包装函数,执行验证逻辑,然后调用原函数或者进行重定向。 同时,用户可能需要了解装饰器的语法结构,即使用@符号,以及如何将装饰器应用到视图函数上。例如,在路由装饰器下方添加@login_required,确保该路由需要登录才能访问。 还需要注意一些可能的错误,比如忘记在装饰器内部调用原函数,或者没有正确处理重定向。另外,可能需要提到装饰器的顺序问题,因为在Flask中,路由装饰器应该是最外层的。 最后,总结装饰器的优势,比如代码复用、非侵入式修改、提高可维护性等。确保用户明白装饰器如何简化登录验证的逻辑,避免在每个视图函数中重复编写相同的检查代码。</think>Python装饰器用于登录验证的实现原理及步骤: 1. 装饰器本质 装饰器是遵循闭包原理的高阶函数,通过@语法糖实现对被装饰函数的包裹,在不修改原函数代码的情况下增加验证功能。 2. 典型实现流程 ```python from functools import wraps from flask import session, redirect, url_for def login_required(func): @wraps(func) # 保持原函数元信息 def wrapper(*args, **kwargs): # 验证逻辑:检查session中是否存在登录标识 if 'user_id' not in session: return redirect(url_for('login')) # 未登录跳转到登录页 return func(*args, **kwargs) # 已登录则执行原函数 return wrapper ``` 3. 框架应用示例(Flask): ```python @app.route('/dashboard') @login_required # 装饰器在路由下方使用 def dashboard(): return '欢迎进入控制面板' ``` 4. 执行顺序解析: 当访问/dashboard时: ① 触发login_required装饰器 ② wrapper函数检查session ③ 验证通过 → 执行dashboard() ④ 验证失败 → 重定向到登录页 5. 优势特点: - 非侵入式:无需修改业务逻辑代码 - 集中管理:统一维护验证逻辑 - 灵活组合:可叠加多个装饰器(权限验证+日志记录等) 6. 进阶用法: ```python # 带参数的装饰器(用于角色验证) def role_required(role_name): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): if session.get('role') != role_name: return abort(403) # 权限不足 return func(*args, **kwargs) return wrapper return decorator # 使用示例 @app.route('/admin') @login_required @role_required('admin') # 装饰器叠加使用 def admin_panel(): return '管理员界面' ``` 7. 注意事项: - 保持函数签名:始终使用@wraps保留原函数信息 - 会话管理:需配合完善的session机制 - 装饰器顺序:在Flask中路由装饰器@app.route应位于最外层 - 异常处理:建议添加CSRF保护等安全措施 通过装饰器实现登录验证,可以有效实现以下功能: 1. 拦截未授权访问 2. 统一处理权限逻辑 3. 保持业务代码纯净 4. 提升系统安全性 5. 方便权限体系扩展
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值