django-rest-framework Routersを翻訳してみた。

#Usage
##Routersの説明

```python:urls.py
from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls
```
registerメソッドには、下記の２つの引数が必須となります。
>`prefix` - URLのプレフィックス。
>`viewset` - viewset classを指定。

オプションで、追加の引数も指定可能です。
>`base_name` - ベースはURLに使用されます。

もし、base_name設定されていない場合、
veiwsetのmodel、またはqueryset属性を元に
自動的に生成されます。

モデルまたは、クエリセット属性がないveiwsetを登録する場合、
`base_name`の設定が必要です。

上記の例として、以下のURLパターンとなります。
>* URL pattern: `^users/$` Name: `'user-list'`
>* URL pattern: `^users/{pk}/$` Name: `'user-detail'`
>* URL pattern: `^accounts/$` Name: `'account-list'`
>* URL pattern: `^accounts/{pk}/$` Name: `'account-detail'`

※`base_name`引数は、ビュー名のパターンの最初の部分を指定するために使用される。
上記の例でいうと、`users`または`accounts`部分です。
通常は、 `base_name`引数を指定する必要はありませんが、
もし、`viewset`の`get_queryset`メソッドをカスタマイズしていた場合、
`.queryset`属性が設定されていないと下記のようなエラーが発生します。

```py
'base_name' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.
```

##routersの使い方
routerインスタンスの`.urls`属性は、URLパターンのリストが返却されます。
これについての使用方法は、複数あるので紹介していきます。

たとえば、既存のビューのリストにrouter.urlsを追加することができます。  


```python:urls.py
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
]
urlpatterns += router.urls
```

djangoの手法で下記のように書くこともできます。

```python:urls.py
urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    url(r'^', include(router.urls))
]
```

ルータのURLパターンの、ネームスペースを指定することができます。

```python:urls.py
urlpatterns = [
    url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
    url(r'^api/', include(router.urls, namespace='api'))
]
```

###エキストラリンクとアクション  
viewsetのmethodに、`@detail_route` `@list_route`のdecoraterを使用することで、ルーティングすることができます。

例)UserViewSetクラスのmethodを、decoraterで、ルーティングします。

```python:views.py
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import detail_route

class UserViewSet(ModelViewSet):
    ...

    @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf])
    def set_password(self, request, pk=None):
        ...
```

以下のURLパターンは、さらに生成されることになります。  

* URL pattern: `^users/{pk}/set_password/$` Name: `'user-set-password'`  

作成したアクションに、自動で生成されるデフォルトのURLを使用したくない場合は、  
url_pathパラメータを使用して、カスタマイズすることができます。  

例) カスタムアクションへのURLを変更する場合は `^users/{pk}/change-password/$`, 下記のように書くことができます。:


```python:views.py
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import detail_route

class UserViewSet(ModelViewSet):
    ...

    @detail_route(methods=['post'], permission_classes=[IsAdminOrIsSelf], url_path='change-password')
    def set_password(self, request, pk=None):
        ...
```
上記の例では、以下のURLパターンを生成しています。  

* URL pattern: `^users/{pk}/change-password/$` Name: `'user-change-password'`  
 
# API Guide
## SimpleRouter

routerには、 `list`, `create`, `retrieve`, `update`, `partial_update` , `destroy` アクションのルートが含まれています。
viewsetのmethodを、`@detail_route`または`@list_route`デコレータを使用して、ルーティングを追加することができます。


<TABLE>
<TR><TH>URL Style</TH><TH>HTTP Method</TH><TH>Action</TH><TH>URL Name</TH></TR>
<TR><TD ROWSPAN=2>{prefix}/</TD><TD> GET </TD><TD>list</TD><TD ROWSPAN=2>{basename}-list</TD></TR>
<TR><TD>POST</TD><TD>create</TD></TR>
<TR><TD>{prefix}/{methodname}/</TD><TD>GET, or as specified by `methods` argument</TD><TD>`@list_route` decorated method</TD><TD>{basename}-{methodname}</TD></TR>
<TR><TD ROWSPAN=4>{prefix}/{lookup}/</TD><TD> GET </TD><TD> retrieve </TD><TD ROWSPAN=4>{basename}-detail</TD></TR>
<TR><TD>PUT</TD><TD>update</TD></TR>
<TR><TD>PATCH</TD><TD>partial_update</TD></TR>
<TR><TD>DELETE</TD><TD>destroy</TD></TR>
<TR><TD>{prefix}/{lookup}/{methodname}/</TD><TD>GET, or as specified by `methods` argument</TD><TD>`@list_route` decorated method</TD><TD>{basename}-{methodname}</TD></TR>
</TABLE>

デフォルトではSimpleRouterによって作成されたURLは、末尾にスラッシュが付加されます。
これは、ルータのインスタンスを作成するときに、trailing_slash引数をFalseに設定することで、解除することができます。

```python:
router = SimpleRouter(trailing_slash=False)
```

Djangoでは、末尾のスラッシュが使用されますが、
Railsや他のフレームワークなど、デフォルトで使用されていない場合もあります。

スラッシュの有無は、好みによりますが、JavaScriptのフレームワークで、仕様が決められている場合があるので、
注意してください。


The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the<code><FONT COLOR='RED'> lookup_value_regex</FONT></code> attribute on the viewset. 


例) 下記は、検索をUUIDに制限する場合です。

```py
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    lookup_field = 'my_model_id'
    lookup_value_regex = '[0-9a-f]{32}'
```

<br/>
[PR]
[![長方形-システム開発002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38197/36301a76-6238-c8f4-1cb8-691642889ca0.png)](https://www.co.task.site?pr=qiita)