Build a Backend REST API - 27
에서 test 코드를 짜봤는데요. 실제로 view짜볼게요.
현재는 serializer.py파일에는 UserSerializer
클래스가 있는데요.
여기에 update()
메소드를 작성하여 user객체를 업데이팅 되도록 할거에요.
또 views.py 파일에는 generics 모듈의 RetrieveUpdateAPIView
클래스를 상속받아 클래스를 짜보도록 할게요.
user/views.py 파일 첫째줄에 authentication, permission를 입력할게요. 인증인가에 관련한 부분이에요.
RetrieveUpdateAPIView
를 상속받아 클래스 ManageUserView
만들게되는데요. 부모클래스 이름이 빡! 느낌오조. 읽기와 수정에 특화된 API라는점!
우리가 구현할 endpoint에 인증과 인가 기능이 있어야 하므로authentication_classes
, permission_classes
를 정의하도록 할게요.
views.py👨🔧
from rest_framework import generics, authentication, permission
...
...
...
class ManageUserView(generics.RetrieveUpdateAPIView):
"""Manage the authenticated user"""
serializer_class = UserSerializer
authentication_classes = (authentication.TokenAuthentication,) # cookie , Token 등등
permission_classes = (permissions.IsAuthenticated,) # 등록된 유저만 접근할수 있도록함
# retrieve and return authenticated user
# this method is also required for update (patch)
def get_object(self):
"""Retrieve and return authentication user"""
return self.request.user
serializers.py👨🏭
create()메서드 아래에 update()메서드를 정의할게요
눈여겨 볼 만한 것들이 몇개 있는데요.
pop()
메서드 리스트의 메서드가 아닌 딕셔너리의 메서드에요. 키워드에 해당하는 키-벨류
를 지워버리거나 만약 해당 키가 없다면 None
을 반환해요. super()
메서드는 ModelSerializer
's의 update를 사용할 수 있게 작동해요.class UserSerializer(serializers.ModelSerializer):
"""Serializer for the users object"""
class Meta:
model = get_user_model()
fields = ('email', 'password', 'name')
extra_kwargs = {'password': {'write_only' : True, 'min_length': 5}}
def create(self, validated_data):
"""Create a new user with encrypted password and return it"""
return get_user_model().objects.create_user(**validated_data)
def update(self, instance, validated_data):
"""Update a user, setting the password correctly and return it"""
password = validated_data.pop('password', None) # delete the 'password' key in dict if it exists or return None
user = super().update(instance, validated_data)
if password:
user.set_password(password)
user.save()
return user
urls.py👨💼
from django.urls import path
from user import views
app_name = 'user'
urlpatterns = [
...
...
path('me/', views.ManageUserView.as_view(), name='me'), # new
]
이번에는 성공했어요~
❯ docker-compose run --rm app sh -c "python manage.py test"
Starting recipe-app-api2_db_1 ... done
Creating recipe-app-api2_app_run ... done
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...Waiting for database...
Database unavailable, waiting 1 second...
Database unavailable, waiting 1 second...
Database unavailable, waiting 1 second...
Database unavailable, waiting 1 second...
Database unavailable, waiting 1 second...
Database available!
.Waiting for database...
Database available!
...............
----------------------------------------------------------------------
Ran 19 tests in 1.481s
OK
Destroying test database for alias 'default'...
정말 괜찮은 크롬 익스텐션 하나 소개해드릴 건데요.
modheader
라고 해요. 가볍게 익스텐션 설치해주세요.
특히 header부분을 수정하는걸 간편하게 해줘요.
만약 docker-compose up
-> 127.0.0.1:8000/api/create/ -> ../token/ -> .../me/ url로 가기 위해선 중간에 발급 받은 토큰을 다운받은 modeheaders 익스텐션을 실행해서 header부분의 authentication을 선택하고 value값에는 token 토큰값
이렇게 넣어줄게요. 중간에 띄워쓰기 공백이 있다는점! 놓치지 마세요.
기본 장고에서 제공하는 validation기능들과 django restframework의 인증, 인가 기능들에 대한 이해가 있어야 끌어다가 어느 시점에 적절히 사용하고 이를 커스터마이징하여 이용할 수 있을 것 같다는 생각이 든다. 단순히 그냥 따라한다기 보단?!
왜?! 이걸 사용하는지에 대한 더 한차원 깊은 생각이 있어야 상황에 따라 유연히 대응할 수 있을 것 같다.