Django - 避免在视图中重复代码的提示

2023-11-25

我正在从 PHP 背景转向通过 python 进行 Django 开发,主要是为了解决我认为最有意义的 MVC(或 MVT),尽管在这种模式中我开始注意到有很多重复的代码我的观点。

例如,登录时我有关于我希望出现在每个页面上的用户的信息,尽管在使用 render_to_response 时并且在每个视图中这是必需的,我必须获取该信息并将其传递给 render_to_response 函数。

我想知道减少重复代码的最有效方法是什么,这些代码本质上是特定应用程序中所有视图中所必需的。

提前致谢。


就我个人而言,我是装饰器的忠实粉丝,装饰器是一个并非 Django 特有的 Python 功能。装饰器是高阶函数之上的完美语法糖,它们对于减少视图中的样板文件特别有用——您可以快速定义一个通用的包装函数,您可以在其中放置重复的代码,以便于重用和方便。 -停止重构。

向您展示可能比解释它们如何工作更容易。这是一个简化的视图示例:

def listpage(request):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.filter(visible=True).order_by("-modifydate")
    }))

def itemlist_tags(request, tags):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
    }))

...但是然后说您想让这些页面要求用户登录。您可以添加登录代码,如下所示:

def listpage(request):
    if not request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponse(render_to_string("itemlist.html", {
            "items": Item.objects.filter(visible=True).order_by("-modifydate")
        }))

def itemlist_tags(request, tags):
    if not request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponse(render_to_string("itemlist.html", {
            "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
        }))

...即使对于一个人为的例子来说,它也开始变得明显更大和重复。您可以使用装饰器使您的函数再次精简,如下所示:

从装饰器导入装饰器

@decorator
def loginrequired(f, request, *args, **kwargs):
    if request.user.is_authenticated():
        return f(request, *args, **kwargs)
    else:
        return HttpResponseRedirect("/")

@loginrequired
def listpage(request):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.filter(visible=True).order_by("-modifydate")
    }))

    @loginrequired
def itemlist_tags(request, tags):
    return HttpResponse(render_to_string("itemlist.html", {
        "items": Item.objects.tagged(name=tags).filter(visible=True).order_by("-modifydate"),
    }))

@loginrequired
def another_such_function(request):
    (...)

@loginrequired
def and_again(request):
    (...)

所发生的情况是装饰器函数在函数定义时执行。我的示例中的“f”是一个对象,表示应用装饰器的函数,您可以以无休止的方式对其进行操作。

这需要装饰器库,它在 PyPI 上是免费的,你会发现还有许多不错的 Python 内容。

您不需要这个库来编写装饰器函数,但它很有帮助,尤其是在开始时。他们可以做更多的事情——任何可调用的都可以是装饰器;您可以装饰类方法并拦截self多变的;装饰器可以链接起来,如下所示:

@second
@first
def originalfunction(*args):
    (...)

如果这个概念激起了您的兴趣,我将把对如此简单的高阶函数操作的探索留给您。对于您或任何其他好奇的新 Python 爱好者,我还有更多示例。祝你好运。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django - 避免在视图中重复代码的提示 的相关文章

随机推荐