【问题标题】:Pass Queryset from decorator to function将查询集从装饰器传递给函数
【发布时间】:2018-05-12 02:59:33
【问题描述】:

我有一个装饰器,它执行与它所附加的函数相同的查询。有没有办法只从装饰器传递查询集,这样我就不必运行两次查询?

decorator.py

def is_wifi_author(func):
    def wrapper(request, wifi_id, **kwargs):
        wifi = get_object_or_404(Wifi, pk=wifi_id)             # Queryset

        # Is this correct?    
        if request.user != wifi.author:
            return redirect('youshallnotpass')

        return func(request, wifi_id, **kwargs)

    return wrapper

views.py

@is_wifi_author
def edit(request, wifi_id):
    # print(request)
    wifi = get_object_or_404(Wifi, pk=wifi_id)                 # Same queryset

    # The rest of the view

    return render(request, 'app/template.html')

是的,只是检查用户是否有权编辑帖子。欢迎任何cmets。

【问题讨论】:

    标签: python django decorator


    【解决方案1】:

    是的,可以使用 kwargs:

    def is_wifi_author(func):
        def wrapper(request, wifi_id, **kwargs):
            wifi = get_object_or_404(Wifi, pk=wifi_id)             # Queryset
    
            # Is this correct?
            if request.user != wifi.author:
                return redirect('youshallnotpass')
    
            return func(request, wifi_id, wiki=wiki, **kwargs)
    
        return wrapper
    
    
    @is_wifi_author
    def edit(request, wifi_id, wiki=None):
        """wiki argument is gonna be updated by the is_wifi_author decorator"""
        print('Yeii, a wiki', wiki)
        # The rest of the view
    
        return render(request, 'app/template.html')
    

    虽然我认为@Ubaid 的回答提到了一个有效的观点。

    【讨论】:

    • 我也同意@Ubaid,尽管在这种情况下我正在创建我的第一个自定义装饰器,所以我在这个过程中学到了很多东西。另外,我可以将它们重定向到我想要的任何地方。
    • 太棒了!我已经使用这种方法来防止执行装饰函数(例如,没有可用的连接),并且我通常会引发异常。
    【解决方案2】:

    既然可以做到,为什么还要使用装饰器

    wifi = get_object_or_404(Wifi, pk=wifi_id, author=request.user) 
    

    【讨论】:

      猜你喜欢
      • 2021-11-21
      • 2021-11-15
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 2016-02-14
      • 2014-11-17
      • 1970-01-01
      相关资源
      最近更新 更多