urls.py中prepend_urls和urlpatterns之间的区别

时间:2015-03-12 19:48:35

标签: django rest tastypie

我在Django上有一个带有TastyPie的REST API,它包含在一个资源上,比如ProductResource。该资源可通过http://my_url/api/product访问。

我的ProductResource类中还有一个名为addNew的函数,它应该处理添加新产品的请求。我想将此方法链接到http://my_url/api/product/new等网址。

一种选择是覆盖prepend_urls,如下所示:

def prepend_urls(self):
    return [
        url(r"^(?P<resource_name>%s)/addNew%s$" %
            (self._meta.resource_name, trailing_slash()),
            self.wrap_view('addNew'), name="product_add_new"),
    ]

这可以按预期工作。我假设另一个选择是使用urls.py,并在那里定义终点。我试图这样做,并将此行添加到我的urlpatterns

url(r"^(?P<resource_name>ProductResource)/addNew/$", ProductResource.addNew, name="product_add_new")

当我这样做时,我收到以下错误:

unbound method addNew() must be called with ProductResource instance as first argument (got WSGIRequest instance instead)

这是可以理解的。所以我的问题是,是否可以通过urls.py而不是prepend_urls将资源内的方法绑定到网址?如果是,那么正确的语法是什么?如果不是,prepend_urlsurls.py之间有什么区别?

由于

1 个答案:

答案 0 :(得分:1)

好吧,你不能直接将addNew这样的方法映射到url,因为url()中使用的callable必须作为第一个参数接收请求。如果您真的想将URL映射到资源方法,您可以这样做:

def my_view(request):
    resource = MyResource(api_name='myapi')
    resource.addNew(request)

然后在url()

中映射此视图
url(r"^(?P<resource_name>ProductResource)/addNew/$", my_view, name="product_add_new")

关于prepend_urls()会发生什么事情,你在url()中用作callable的是wrap_view()的返回,而不是方法本身。而wrap_view()返回的是一个将请求作为其第一个参数的可调用对象。

https://github.com/django-tastypie/django-tastypie/blob/master/tastypie/resources.py#L188