0

我有一个类似的coce:

def override_urls(self):
    return [
        url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
    ]

这会产生如下 URL:

/api/v1/nodes/<slug>/

self.get_resource_uri(bundle)除了返回之外,一切都很好/api/v1/nodes/<id>/,我无法有效地将当前 URL 与资源 URI 进行比较。

我究竟做错了什么?

解决方案:工作代码

我在这里实现了建议的解决方案: https ://github.com/ninuxorg/nodeshot/blob/refactoring/nodeshot/core/base/resources.py

欢迎任何额外的改进反馈。

4

2 回答 2

6

您可以覆盖get_resource_uri您的资源以返回正确的 uri。毕竟,正确的那个是带有蛞蝓的那个,因为那是你的资源捕获的(第一个)。

更新

这样做的正确方法实际上是跳过override_urls并将其放在资源的 Meta 上:

detail_uri_name = 'slug'

TLDR 背景

我挖得更深了,看起来有一个更好的地方来实现这个。get_resource_uri(间接)调用的默认实现self.detail_uri_kwargsthen reverse

detail_uri_kwargsin的默认实现ModelResource只是查找self._meta.detail_uri_name(其名称不直观),然后从模型中获取该键。 detail_uri_name默认为pk.

如果您只是在此处提供不同的名称,则可以跳过 override_urls 和 get_resource_uri!

像这样的东西(基于OP评论中链接的代码):

from tastypie.resources import ModelResource
from tastypie.bundle import Bundle

class BaseSlugResource(ModelResource):
    """ Base Model Resource using slug urls """

    class Meta:
        abstract = True
        detail_uri_name = 'slug'

我不确定资源是否Meta是继承的(我猜他们不是),所以这可能不能作为基类工作。幸运的是,所需的一行可能可以很好地粘贴到需要它的每个资源中。

于 2012-09-20T16:51:15.217 回答
1

即使@dokkaebi 的答案被标记(并且部分)正确,我也想用一个工作示例来清理它。唯一缺少的部分是您仍然必须预先添加将被解析为列表等的url 。

from tastypie.resources import ModelResource
from myapp.models import SomeModel

class BaseSlugResource(ModelResource):
    """ Base Model Resource using slug urls """

    class Meta:
        queryset = SomeModel.objects.all()
        detail_uri_name = 'slug'

    def prepend_urls(self):
        return [
            url(r'^(?P<resource_name>%s)/(?P<slug>[\w\.-]+)/$' % self._meta.resource_name, self.wrap_view('dispatch_detail'), name='api_dispatch_detail'),
        ]

这将显示正确的 resource_uri 列表以及资源获取。但是,您很可能会丢失 {schema} 资源(即 /api/posts/schema/),因为它也被视为 slug。

于 2013-03-06T15:26:20.767 回答