🗂

Django REST framework JSON:API(DJA)に独自のモデルのビューをカスタマイズする

2023/06/05に公開

概要

以下の記事で追加したモデルのビューをカスタマイズしてみます。

https://zenn.dev/nakamura196/articles/db6caba4f8aaa5

sort

ordering_fieldsを追加してみます。

/django-rest-framework-json-api/example/views.py
...
class UserInfoViewset(ModelViewSet):
    ordering_fields = ("user_name", ) # ここを追加
    
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    def get_object(self):
        entry_pk = self.kwargs.get("entry_pk", None)
        if entry_pk is not None:
            return Entry.objects.get(id=entry_pk).blog

        return super().get_object()
	
...

結果、「Filters」の表示で、user_nameのみが選択できるようになりました。

例えば、ageでソートを行うと、validation errorが返却されました。

フィルタ

/django-rest-framework-json-api/example/views.py
...
class UserInfoViewset(ModelViewSet):
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    ordering_fields = ("user_name", )
    
    # ここから下を追加

    # override the default filter backends in order to test QueryParameterValidationFilter
    # without breaking older usage of non-standard query params like `page_size`.
    filter_backends = (
        QueryParameterValidationFilter,
        OrderingFilter,
        DjangoFilterBackend,
        SearchFilter,
    )

    rels = (
        "exact",
        "iexact",
        "contains",
        "icontains",
        "gt",
        "gte",
        "lt",
        "lte",
        "in",
        "regex",
        "isnull",
    )
    filterset_fields = {
        "id": ("exact", "in"),
        "user_name": rels
    }
    search_fields = ("user_name", )
    ...
...

上記により、以下のようなフィルタが可能になりました。

http://localhost:8000/user-info?filter[user_name.contains]=nakamura

idについては、exactinのみを許可しているので、以下はvalidationエラーになりました。

http://localhost:8000/user-info?filter[id.contains]=2

swagger-uiを確認してみると、filterが正しく設定されていました。

http://localhost:8000/swagger-ui/

ReadOnlyModelViewSet

これは、Django REST frameworkの機能のようですが、ReadOnlyModelViewSetを与えることで、閲覧のみに限定したビューを作成できました。

/django-rest-framework-json-api/example/views.py
...
class UserInfoViewset(ReadOnlyModelViewSet): # ここを変更
    queryset = UserInfo.objects.all()
    serializer_class = UserInfoSerializer

    ordering_fields = ("user_name", )
...

swagger-uiを確認してみると、getのみに設定されました。

まとめ

理解が不十分な点が多いですが、フィルタの実装の参考になりましたら幸いです。

Discussion