【问题标题】:Django Tastypie Prefix URL resource with slug带有 slug 的 Django Tastypie 前缀 URL 资源
【发布时间】:2012-08-17 20:08:58
【问题描述】:

我正在尝试构建如下 API:

api/v1/<client_slug>/track/expenses

但是,至少在这一点上,我并没有真正需要返回 /clients 的任何数据,因此我希望避免必须创建 ClientResource 来遵循 REST 标准。下面是我的 ExpenseResource 的一个示例。

class ExpenseResource(ModelResource):
    class Meta:
        resource_name = 'expenses'
        queryset = Expense.objects.all() # Wish to filter by client_slug
        include_resource_uri = False

        authentication = OAuthTokenAuthentication()
        authorization = Authorization() # allow GET/PUT/POST/DELETE/PATCH

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

在我的ExpenseResource 中包含 client_slug 的最佳处理方式是什么?我想通过提供的 client_slug 过滤我的费用,我应该怎么做?谢谢!

【问题讨论】:

    标签: django api rest tastypie


    【解决方案1】:

    其实很简单。您可以覆盖 base_urls() 或使用 override_urls()prepend_urls() 来提供接受 client_slug 的自定义 URL。

    Tastypie 对每个资源执行以下操作:

    def base_urls(self):
        """
        The standard URLs this ``Resource`` should respond to.
        """
        # Due to the way Django parses URLs, ``get_multiple`` won't work without
        # a trailing slash.
        return [
            url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
            url(r"^(?P<resource_name>%s)/schema%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_schema'), name="api_get_schema"),
            url(r"^(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)/$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"),
            url(r"^(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]
    

    你需要的是:

        return [
            url(r"^(?P<client_slug>\w+)/(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_list'), name="api_dispatch_list"),
            url(r"^(?P<client_slug>\w+)/(?P<resource_name>%s)/schema%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('get_schema'), name="api_get_schema"),
            url(r"^(?P<client_slug>\w+)/(?P<resource_name>%s)/set/(?P<pk_list>\w[\w/;-]*)/$" % self._meta.resource_name, self.wrap_view('get_multiple'), name="api_get_multiple"),
            url(r"^(?P<client_slug>\w+)/(?P<resource_name>%s)/(?P<pk>\w[\w/-]*)%s$" % (self._meta.resource_name, trailing_slash()), self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
        ]
    

    只需使用上述方法之一来提供这些方法,然后我相信client_slug 将在所有接受**kwargs 的Tastypie 方法中可用。

    我没有测试过,但是给出了:

     objects = self.obj_get_list(request=request, **self.remove_api_resource_names(kwargs))
    

    get_list() 中,它甚至可以为您过滤开箱即用的客户费用。

    【讨论】:

    • 太棒了,谢谢你的建议。 :) 我现在正忙于其他事情,但是当我有机会时,我会调查一下,让你知道它是怎么回事! (并且可能会接受你的回答):)
    • 听起来不错。很少有事情会出错,但我认为大方向应该是好的,所以请告诉我进展如何,我很乐意帮助您解决任何问题。
    • 已经有一段时间了,但我似乎无法让它工作。我已经设置了我的 ExpenseResource 以实现 override_urls 并设置了您在上面定义的 URL。我似乎仍然可以点击 /api/v1/expenses/,但是当我点击 /api/v1/client_slug/expenses/ 时得到 404。就像 URL 从未向 Django 注册一样。有什么想法吗?
    • 这是 REGEX 和我的中间件的问题 - 红鲱鱼。感谢您的回答,大部分都成功了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2013-11-30
    • 2012-03-05
    • 1970-01-01
    相关资源
    最近更新 更多