【问题标题】:Access request user and url parameters in django decoratordjango装饰器中访问请求用户和url参数
【发布时间】:2026-01-26 12:25:01
【问题描述】:

我试图通过创建一个装饰器来处理总是重复的简单逻辑来消除冗余代码。基本上我创建的每个视图都有以下逻辑来检查用户是否在班级中。

@login_required
def view(request, class_id):

    class_ = UserClasses.objects.get(user=request.user, class_id=class_id)

    # if the user is in the class
    if class_:

我想做以下事情:

查看:

@user_passes_test(in_class(request.user, class_id))
@login_required
def view(request, class_id):

装饰者:

from apps.classes.models import UserClasses

def in_class(request, class_id):
    class_ = UserClasses.objects.get(user=request.user, class_id=class_id)
    if class_:
        return true
    else:
        return false

实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: python django decorator python-decorators


    【解决方案1】:

    你的装饰器应该是这样的

    def user_passes_test(old_fuction):
        def new_function(request, class_id, *args, **kwargs):
            try:
                class_ = UserClasses.objects.get(user=request.user, class_id=class_id)
            except Exception, e:
                return HttpResponse('ERROR: User not present in the class')
            return old_fuction(request, class_id, *args, **kwargs)
        return new_function
    

    如果UserClasses包含userclass_id的行(假设userunique),将执行视图函数。否则它将返回错误响应(错误:用户未出现在课堂上)。

    而你的view函数应该是

    @user_passes_test
    @login_required
    def view(request, class_id):
    

    如果你想在视图函数中添加class_ 对象,你可以通过简单的修改来实现。像这样修改你的装饰器

    def user_passes_test(old_fuction):
        def new_function(request, class_id, *args, **kwargs):
            try:
                class_ = UserClasses.objects.get(user=request.user, class_id=class_id)
            except Exception, e:
                return HttpResponse('ERROR: User not present in the class')
            return old_fuction(request, class_id, class_, *args, **kwargs)
        return new_function
    

    而且视图功能应该是

    @user_passes_test
    @login_required
    def view(request, class_id, class_obj):
    

    其中class_obj 包含class_ 对象

    【讨论】:

    • 这有点晚了,但万一有人遇到问题 - 在 except 块中,语法是 'except Exception as e:'