@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
	...
    
@user_router.put('/{user_nickname}', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):
	...

여기 2개의 Method가 있다. 사용방법에는 전혀 이상이 없지만 밑에 put 메소드를 실행하면 Method Not Allowed 오류가 발생한다. header를 살펴보면 분명히 PUT Method로 보냈는데 GET Method가 실행된다. 첫번째 GET Method가 실행되는 것이다. (맨 위에 것으로 인식한다.)

 

왜 이런 문제가 발생할까? 문제는 Django Resolver의 문제이다. url pattern이 같으면 같게 인식하는 문제이다. 

 

그렇다면 해결을 어떻게 해야할까?

 

방법이 있다. 

 

@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
    
@user_router.put('/{user_nickname}/update', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):

위와 같이 url pattern을 다르게 주는 것이다. 하지만 이 방법은 api 규칙에는 맞지 않다. 

 

올바른 방법은 

@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
    
@user_router.put('/{user_id}', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):

애초에 파라미터 값을 같게 주는 것이다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Router  (0) 2021.12.07
Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29

https://django-ninja.rest-framework.com/tutorial/routers/

 

Routers - Django Ninja

Routers Real world applications can almost never fit all logic into a single file. Django Ninja comes with an easy way to split your API into multiple modules using Routers. Let's say you have a Django project with a structure like this: ├── myprojec

django-ninja.rest-framework.com

 

Django Ninja에서 App마다 api.py와 schema.py를 생성해서 관리를 해야한다. 하지만 App이 많아질 수록 관리하기도 힘들어진다. 이럴경우 Router 기능을 사용하면 된다. 

 

 

1. Router 폴더 구조

 

각 App마다 api.py를 생성한다. (schema.py도 생성해준다.)

 

 

2. App별 api.py 작성

 

course/api.py

from typing import List

from ninja import Router

from .models import CoursePage
from . import schema


course_router = Router()

@course_router.get('/', response=List[schema.CourseSchema])
def courses(request):
    return CoursePage.objects.all()

@course_router.get('/{course_id}', response={200: schema.CourseSchema, 404: schema.NotFoundSchema})
def course(request, course_id: int):
    try:  
        course = CoursePage.objects.get(id=course_id)
        return course
    except CoursePage.DoesNotExist:
        return 404, {"message": "코스 페이지가 존재하지 않습니다."}

간단하게 CoursePage라는 모델의 정보를 가져오는 api를 구축하였다. 

Schema와 endpoint 구현은 기존의 NinjaAPI와 동일하게 작성하면 된다.

 

 

3. Project api.py 생성

 

myproject/api.py

import orjson

from ninja.renderers import BaseRenderer
from ninja import NinjaAPI

from course.api import course_router


# api 렌더링 (한글이 깨지는 문제) 
class ORJSONRenderer(BaseRenderer):
    media_type = "application/json"

    def render(self, request, data, *, response_status):
        return orjson.dumps(data)

api = NinjaAPI(renderer=ORJSONRenderer())

# 라우터 등록
api.add_router('/courses/', course_router)

api.add_router를 통해 url를 지정해주면 된다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Method Not Allowed 오류  (0) 2021.12.09
Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29

Django Ninja API에서 한글이 제대로 출력 되지 않는 문제가 있을 것이다. 

다음과 같이 해결하면 된다.

 

https://django-ninja.rest-framework.com/tutorial/response-renderers/#xml-renderer-example 

 

Response renderers - Django Ninja

Response renderers The most common response type for a REST API is usually JSON. Django Ninja also has support for defining your own custom renderers, which gives you the flexibility to design your own media types. Create a renderer To create your own rend

django-ninja.rest-framework.com

 

1) orjson 설치

pip install --upgrade orjson

 

 

2) api 수정

import orjson
from ninja import NinjaAPI
from ninja.renderers import BaseRenderer


class ORJSONRenderer(BaseRenderer):
    media_type = "application/json"

    def render(self, request, data, *, response_status):
        return orjson.dumps(data)

api = NinjaAPI(renderer=ORJSONRenderer())

렌더링 문제였고 orjson을 통해 해결 하였다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Method Not Allowed 오류  (0) 2021.12.09
Django Ninja Router  (0) 2021.12.07
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29

https://vicapor.tistory.com/109

 

Django Ninja Tutorial 4

https://vicapor.tistory.com/108 Django Ninja Tutorial 3 https://vicapor.tistory.com/107 Django Ninja Tutorial 2 https://vicapor.tistory.com/7 Django Ninja Tutorial 1 Django Ninja 공식 페이지 : https..

vicapor.tistory.com

 

이번에는 Schema를 작성하는 방법에 대해서 알아보려고 한다. 

 

초기 버전 Django Ninja에서는 직접 자료형을 명시해줘야했다. 

 

1.

class TrackSchema(Schema):
    title: str
    artist: str
    duration: float
    last_play: datetime

 

 

하지만 버전이 업그레이드가 되고 다음과 같은 2가지 방법으로 작성이 가능하다. 

 

2.

from ninja import ModelSchema

class TrackSchema(ModelSchema):
    class Config:
        model = Track
        model_fields = ['title', 'last_play', 'artist', 'duration']

 

 

3.

from ninja.orm import create_schema
from .models import Track

TrackSchema = create_schema(Track, fields=['title', 'last_play', 'artist', 'duration'])

 

작성한 모델에 대해 자동으로 Schema를 만들어주니 더욱 편리하게 사용할 수 있을 것이다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Router  (0) 2021.12.07
Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29
Django Ninja Tutorial 2  (0) 2021.11.29

https://vicapor.tistory.com/108

 

Django Ninja Tutorial 3

https://vicapor.tistory.com/107 Django Ninja Tutorial 2 https://vicapor.tistory.com/7 Django Ninja Tutorial 1 Django Ninja 공식 페이지 : https://django-ninja.rest-framework.com/ 장고 닌자는 FAST API..

vicapor.tistory.com

3편에 이은 4편이다. 이번에는 파일을 업로드 하는 api를 구현해보려고 한다. 

 

 

1. Template 생성

 

1) url

djninja/urls.py

from django.contrib import admin
from django.urls import path
from tracks.api import api
from tracks.views import index

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', api.urls),
    path("index/", index, name='index')
]

 

 

2) view

tracks/views.py

from django.shortcuts import render

# Create your views here.
def index(request):
    return render(request, 'index.html', {})

 

3) template

tracks/templates/index.html

<form method="post" action="{% url 'api-1.0.0:upload' %}" enctype='multipart/form-data'>
    <input type="file" name="file">
    <button type="submit">Submit</button>
</form>

 

 

2. File upload 구현

 

tracks/api.py

@api.post("/upload", url_name='upload')
def upload(request, file: UploadedFile = File(...)):
    data = file.read().decode()
    return {
        'name': file.name,
        'data': data,
    }

 

 

추가)

Django Ninja는 기본적으로 Swagger 기능을 제공해주는데

 

http://127.0.0.1:8000/api/docs 로 접속하면 확인할 수 있다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29
Django Ninja Tutorial 2  (0) 2021.11.29
Django Ninja Tutorial 1  (0) 2021.07.09

https://vicapor.tistory.com/107

 

Django Ninja Tutorial 2

https://vicapor.tistory.com/7 Django Ninja Tutorial 1 Django Ninja 공식 페이지 : https://django-ninja.rest-framework.com/ 장고 닌자는 FAST API에서 영감을 받아서 만들어진 Web FrameWork이다. 빠른속도..

vicapor.tistory.com

Django Ninja Tutorial 2편에 이은 3편이다. 오늘은 API CRUD를 구현해보는 튜토리얼이다. 

 

 

1. POST Method

@api.post("/tracks", response={201: TrackSchema})
def create_track(request, track: TrackSchema):
    track = Track.objects.create(**track.dict())
    return track

Json으로 이루어진 데이터가 정상적으로 통신되었을 때, 201를 응답해주고 Schema의 검증을 통해서 데이터 형식을 확인하고 데이터를 만들어준다. 

 

 

2. PUT Method

@api.put("/tracks/{track_id}", response={200: TrackSchema, 404: NotFoundSchema})
def change_track(request, track_id: int, data: TrackSchema):
    try:
        track = Track.objects.get(pk=track_id)
        for attribute, value in data.dict().items():
            setattr(track, attribute, value)
        track.save()
        return 200, track
    except Track.DoesNotExist as e:
        return 404, {"message": "Track does not exist"}

수정은 먼저 track_id를 통해 수정할 데이터를 가져오고 수정할 데이터를 data에 TrackSchema를 통해 검증한다. 

그리고 setattr을 통해 atrribute와 value를 딕셔너리 형태(Json)로 저장해놓는다. 

 

201: 성공, 400: 문제

 

 

3. DELETE Method

@api.delete("/tracks/{track_id}", response={200: None, 404: NotFoundSchema})
def delete_track(request, track_id: int):
    # curl -X DELETE http://localhost:8000/api/tracks/7729
    try:
        track = Track.objects.get(pk=track_id)
        track.delete()
        return 200
    except Track.DoesNotExist as e:
        return 404, {"message": "Could not find track"}

delete method는 검증할 데이터가 없기 때문에 track을 리턴하지 않는다.

response는 응답 온 데이터 즉 return 한 데이터를 의미한다. 검증할 리턴 값이 없기 때문에 None으로 설정해준다.

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 2  (0) 2021.11.29
Django Ninja Tutorial 1  (0) 2021.07.09

+ Recent posts