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 url 标签和reverse()函数的使用(转)
django.core.urlresolver.reverse - NoReverseMatch:“...”的反向参数“()”和关键字参数“”未找到
用于 JavaScript 的 Django reverse()