对于特定需求(django-jqgrid),我定义了一个类(代表Grid
),我必须提供url
属性。由于我只使用反向URL(没有静态定义),因此我使用reverse_lazy()
。
只要我不必将参数传递给reverse_lazy()
,这就行得很好。但是,如果我想使Grid
特定于某个对象(此处为DocumentSet
),则此url
参数也需要特定于该对象,因此我需要提供reverse_lazy()的参数。
在运行时,我可以访问DocumentSet
因为我将它定义为对象的属性,并且我确保调用此Grid
的第一个函数将此对象作为参数,并设置属性正确。
我尝试使用此代码:
class DocumentGrid(JqGrid):
documentset = None
model = Document
url = reverse_lazy('document-grid-handler', kwargs = {'pk' : documentset.id, })
def get_queryset(self, request):
return self.documentset.documents
def get_json(self, request, documentset):
self.documentset = documentset
return super(DocumentGrid, self).get_json(request)
但当然,由于NoneType object has no attribute 'id'
导入文件时失败。
所以我尝试使用django.utils.functional.lazy()
,将这个琐碎和愚蠢的函数添加到我的模型中:
def get_id(self):
return self.id
使用此代码:
class DocumentGrid(JqGrid):
documentset = DocumentSet
model = Document
url = reverse_lazy('document-grid-handler', kwargs = {'pk' : lazy(documentset.get_id, int), })
def get_queryset(self, request):
return self.documentset.documents
def get_json(self, request, documentset):
self.documentset = documentset
return super(DocumentGrid, self).get_json(request)
现在文件正确导入,没有Django抱怨。 但是,在运行时,我收到以下错误:
Reverse for 'document-grid-handler' with arguments '()' and keyword arguments '{'pk': <function get_id at 0x1a07410>}' not found.
这是正确的方法,但我犯了一个小错误?或者我是否误解了关于懒惰评估的所有内容,应采取完全不同的方法并重写reverse_lazy()
?
答案 0 :(得分:7)
django.utils.functional.lazy()
返回一个懒惰计算的可调用对象,换句话说它会为你提供一个返回延迟值的函数。
参见示例:
l = lazy(lambda : 42, str)
unicode(l) # returns u'<function <lambda> at 0x3a5bcf8>'
lazy_value = l()
unicode(lazy_value) # returns u'42'
但是,如果您要替换self.documentset
函数中的get_json
字段,则您的懒惰调用可能会导致错误的结果。因为它将使用旧的DocumentSet
。
对于JqGrid
,还有另一种解决方案。 JqGrid
为您提供了get_url
方法,默认情况下它只返回self.url
。但您可以覆盖此行为:
class DocumentGrid(JqGrid):
documentset = None
model = Document
url = None
def get_queryset(self, request):
return self.documentset.documents
def get_json(self, request, documentset):
self.documentset = documentset
return super(DocumentGrid, self).get_json(request)
def get_url(self):
return reverse('document-grid-handler', kwargs = {'pk' : self.documentset.id, })