6

介绍

对于特定需求(django-jqgrid),我定义了一个类(代表 a Grid),我必须在其中提供一个url属性。因为我只使用反向 URL(没有静态定义),所以我使用reverse_lazy()这个。

只要我不必将参数传递给reverse_lazy(). 但是,如果我想让它Grid特定于一个对象(这里是 a 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()

4

1 回答 1

8

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, })
于 2013-03-29T13:26:37.070 回答