장고 ninja api 로 리턴을 해주는 api 작성시에 페이지 정보와 전체 카운터, 이전페이지 다음페이지 유무등의 정보를 넣은 객체가 리턴되었으면 한다. 이때 편하게 할 수 있도록 Schema 상속을 통해 이를 해결해 보자.
매번 Schema 를 작성해야 하는데 공통 분모가 되는 필드들이 많이 있다.
이때 마다 매번 같은 내용을 작성하기 귀찮은데 클래스 추상화로 이를 해결할 수 있다.
그냥 코드를 보자.
페이지 정보와 해당 객체들의 리스트가 포함된 Schema 를 아래와 같이 정의해 본다.
각각 results 에 들어가는 객체들은 매번 바뀌니깐 공통 분모만 PaginatedOutSchema 로 정의해 두고
상속해서 사용하도록 한다.
class PaginatedOutSchema(Schema):
total_releases: int
total_pages: int
per_page: int
has_next: bool
has_previous: bool
CompanySchema = create_schema(Company)
class CompanyPaginatedOutSchema(PaginatedOutSchema):
results: List[CompanySchema] = None
위의 코드는 Company 라는 model을 만들고
이 Schema 는 ninja 에서 제공하고 이쓴 create_schema() 로 자동 생성하고,
이 생성된 Schema를 페이지 정보를 넣어서 주는 Schema를 다시 정의한 셈이다.
api 함수에서 사용하는 예는 아래와 같이 사용해 볼 수 있다.
response 를 위해서 만든 Schema로 정의해두고, \
아래 코드를 참고해서 정보를 잘 넣어 주면 된다.
@api.get('company',response=CompanyPaginatedOutSchema)
def list_company(request, page: int = 1):
releases = Company.objects.all().order_by("-created_at")
# code from https://petersimpson.dev/blog/trying-out-django-ninja/
paginator = Paginator(releases, 3)
page_number = page
page_object = paginator.get_page(page_number)
response = {}
response["total_releases"] = page_object.paginator.count
response["total_pages"] = page_object.paginator.num_pages
response["per_page"] = page_object.paginator.per_page
response["has_next"] = page_object.has_next()
response["has_previous"] = page_object.has_previous()
response["results"] = [i for i in page_object.object_list.values()]
return response
받은 정보 값을 JSON 을 그대로 덤프해 보면 아래 처럼 리턴 받을 수 있다.
{
"total_releases": 1,
"total_pages": 1,
"per_page": 3,
"has_next": false,
"has_previous": false,
"results": [
{
"id": 1,
"updated_at": "2021-11-16T06:53:43.216Z",
"created_at": "2021-11-16T06:53:43.216Z",
"name": "회사이름",
"is_deleted": 0
}
]
}
여기서 사용한 기본 틀이 되는 코드 정보는 아래 블로그에서 많이 참고했습니다.
https://petersimpson.dev/blog/trying-out-django-ninja/