Django中reverse()和reverse_lazy()的区别

Posted

技术标签:

【中文标题】Django中reverse()和reverse_lazy()的区别【英文标题】:Difference between reverse() and reverse_lazy() in Django 【发布时间】:2018-07-18 01:55:29 【问题描述】:

我知道我们可以在 FBV 中使用 reverse(),在 CBV 中使用 reverse_lazy()。我知道我们必须在 CBV 中使用reverse_lazy(),因为在导入文件时不会加载 URL(参考:Reverse_lazy and URL Loading?)

我不明白的是:

当我们从 FBV 调用 reverse 时,url 是如何加载的?当我们在 Django 应用程序中导入 urls.py 顶部的视图时,urlpatterns 列表尚未评估。 reverse() 是如何用于 FBV 而不是用于 CBV?

【问题讨论】:

【参考方案1】:
#importme.py
def a():
    print("FUNCTION HELLO")

class B():
    print("CLASS HELLO") 
    

>>> import importme
>>> CLASS HELLO

编辑: 原因:类的创建过程涉及到执行类的主体。

类主体(大约)以exec(body, globals(), namespace) 执行。 [...]一旦类命名空间被 执行类体,通过调用创建类对象 metaclass(name, bases, namespace, **kwds).

https://docs.python.org/3/reference/datamodel.html?highlight=metaclass#executing-the-class-body



我的原始答案文本。你可以忽略它——我只是把它留在里面,因为 mirek 的评论是对它的直接回应:

类属性在导入时进行评估。何时或如何发生这种情况的答案存在于 python 导入系统的深处。

【讨论】:

>> 存在于 python 的导入系统的深处——我认为它存在于类的原则中,而不是在“深度......”中。定义的类必须有它的属性。【参考方案2】:

区别:

    reverse() 在函数中使用,reverse_lazy() 在类中使用。 reverse() 在字符串中使用 & reverse_lazy() 在对象中使用

【讨论】:

【参考方案3】:

Reverse_lazy,顾名思义,是reverse URL 解析器的惰性实现。与传统的 reverse 函数不同,reverse_lazy 在需要该值之前不会执行。

它很有用,因为它在处理可能无法立即知道的 URL 时防止 Reverse Not Found 异常。

我们为什么需要它? 之所以需要它,是因为类属性在导入时进行评估,那时 Reverse 方法将返回“Reverse Not Found”。 稍后根据需要,在其执行时,所有必要的代码 sn-ps 将已经执行,以提供有效的 URL。

【讨论】:

【参考方案4】:

只需了解区别:

reverse() 返回string & reverse_lazy() 返回<object>

【讨论】:

这如何解释奇怪的行为?真心求问。【参考方案5】:

因为:Python 类属性是在声明中评估的。 请阅读此链接:Python class attributes are...

【讨论】:

【参考方案6】:

考虑这两种定义success_url的方式。第一个被注释掉, 二是功能:

class NewJobCBV(LoginRequiredMixin, CreateView):
    template_name = 'company/job.html'
    form_class = newJobForm
    # success_url = reverse_lazy('newJob')

    def get_success_url(self, **kwargs):
        return reverse("newJob")

@CoffeeBasedLifeform :你是对的,类属性是在导入时评估的,我在阅读你的答案后检查了。所以,

    如果我们使用success_url,我们必须使用reverse_lazy()。 如果我们在函数内部进行反转,我们可以使用reverse()

现在很清楚了。

感谢 CoffeeBasedLifeform :)

【讨论】:

以上是关于Django中reverse()和reverse_lazy()的区别的主要内容,如果未能解决你的问题,请参考以下文章

什么是Django中的reverse()

Django url 标签和reverse()函数的使用(转)

django.core.urlresolver.reverse - NoReverseMatch:“...”的反向参数“()”和关键字参数“”未找到

用于 JavaScript 的 Django reverse()

用于 JavaScript 的 Django reverse()

我不知道何时在 django.core.urlresolvers 模块中使用 reverse()