【问题标题】:Django Tastypie Override URL with slug带有 slug 的 Django Tastypie 覆盖 URL
【发布时间】:2012-09-20 14:45:17
【问题描述】:

我也有类似的想法:

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/&lt;id&gt;/ 并且我无法有效地将当前 URL 与资源 URI 进行比较。

我做错了什么?

解决方案:工作代码

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

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

【问题讨论】:

    标签: python django tastypie


    【解决方案1】:

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

    更新

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

    detail_uri_name = 'slug'
    

    TLDR 背景

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

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

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

    类似这样的东西(基于 OP 在 cmets 中链接的代码):

    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'
    

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

    【讨论】:

    • 那么 override_urls 是否正确?我以为我做错了什么导致 get_resource_uri() 返回旧 URL。
    • 不,这是正确的方法——override_urls 是正确的。但请注意,从 Tastypie 0.9.12 开始,override_urls 将被弃用,而支持具有相同功能的 prepend_urls
    • 我在这里尝试了你的建议,它很有效:github.com/ninuxorg/nodeshot/blob/refactoring/nodeshot/core/…你能看出实施有什么问题吗?
    • @nemesisdesign 更新了一个更好的答案。
    【解决方案2】:

    即使@dokkaebi 的答案被标记(并且部分)正确,我也想用一个工作示例来清理它。唯一缺少的部分是您仍然需要prepend 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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-04
      • 2018-10-22
      • 2012-06-26
      • 2020-06-28
      • 2012-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多