이번에는 USER의 데이터를 가져와 보도록 할 것입니다.
유저 데이터는
1. 내 프로필과
2. 다른 상대방의 프로필을 볼 수 있을 것입니다.
나의 프로필은 현재 접속한 나 자신의 값을 가져오면 되기 때문에 별도의 pk값 USER의 ID값이 필요없지만, 상대방의 경우에는 USER의 ID값이 필요하죠?
이런 방식으로 아래 View파일을 만들어 봅니다
#users/views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.views import APIView
from rest_framework import status
from .models import User
from .serializers import RelatedUserSerializer
class MeView(APIView):
def get(self, request):
if request.user.is_authenticated:
return Response(ReadUserSerializer(request.user).data)
def put(self, request):
pass
@api_view(["GET"])
def user_detail(request, pk):
try:
user = User.objects.get(pk=pk)
return Response(ReadUserSerializer(user).data)
except User.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
우선 인증을 하기 위해서 Django RestFramework의 인증 부분을 사용하면 엄청 간편하게 구현할 수 있습니다.
from rest_framework.permissions import IsAuthenticated
class MeView(APIView):
permission_classes = [IsAuthenticated]
...
이런 형태로 permission_class만 해주면 인증 부분은 자동으로 처리해줍니다.
다음은 업데이트를 해주기 위해서 WriteSerializer를 만들어주도록 할 것입니다.
이번에는 ModelSerializer를 사용했고, ModelSerializer를 사용하면 아주 간편하게 처리를 해줄 수 있습니다.
ModelSerializer를 사용해도 Validation을 할 수 있는데, 이는 함수명(self, value): 값을 가지고 하면되는데 반드시 Return데이터는 value의 값을 그래도 리턴해주어야 한다는 점입니다.
#users/serializers.py
class WriteUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ("username", "first_name", "last_name", "email")
def validate_first_name(self, value):
print(value)
return value.upper()
Serializer를 만들었으니 이제 view를 업데이트 해주면됩니다.
#users/views.py
class MeView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
return Response(ReadUserSerializer(request.user).data)
def put(self, request):
serializer = WriteUserSerializer(request.user, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response()
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
아래 코드를 보면 RoomSerializer가 Read,와 Write 두가지가 있는 걸 확인할 수 있는데, Read의 경우는 User의 값을 나타내야 하므로 예를들어 User가 SuperUser인지를 알아야 하기 때문에 User에 대한 정보가 필요하면 ReadRoomSerializer 필요없고 업데이트만을 할 경우에는 WriteRoomSerializer를 사용했는데
ModelSerializer를 사용하면 이 두가지를 합 칠 수 있다.
from rest_framework import serializers
from users.serializers import RelatedUserSerializer
from .models import Room
class ReadRoomSerializer(serializers.ModelSerializer):
user = RelatedUserSerializer()
class Meta:
model = Room
exclude = ()
class WriteRoomSerializer(serializers.ModelSerializer):
class Meta:
model = Room
exclude = ("user", "modified", "created")
def validate(self, data):
if self.instance:
check_in = data.get("check_in", self.instance.check_in)
check_out = data.get("check_out", self.instance.check_out)
else:
check_in = data.get("check_in")
check_out = data.get("check_out")
if check_in == check_out:
raise serializers.ValidationError("Not enough time between changes")
return data
사용자 페이지에 가게되면 좋아요한 콘텐츠를 볼 수 있도록 되어 있지만, 일반적으로 좋아요한 것들이 1000개가 넘어가면 복잡해 지기 떄문에 별도의 favs를 나타내는 URL을 만드는 것이 좋다.
그렇게 하기 위해서 FavsVIew를 만들자.
#users/views.py
class FavsView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
user = request.user
serializer = RoomSerializer(user.favs.all(), many=True).data
return Response(serializer)
def put(self, request):
pk = request.data.get("pk", None)
user = request.user
if pk is not None:
try:
room = Room.objects.get(pk=pk)
if room in user.favs.all():
user.favs.remove(room)
else:
user.favs.add(room)
return Response()
except Room.DoesNotExist:
pass
return Response(status=status.HTTP_400_BAD_REQUEST)
위 코드에서 put 함수를 보면, fav값이 있으면 그 값을 지우고, 없으면 방을 추가하는 개념입니다.
이제 회원을 만드는 방법에 대해서 한번 알아보도록 하겠습니다.
먼저 회원 등록을 하기 위해서 Serializer에서 UserSerializer를 만들어줍니다. 앞서 했던 것처럼 read_only_field를 만들어줍니다.
회원 가입에서 다른 POST방식과 다른 부분은 비밀번호입니다. 비밀번호의 경우에는 serializer에 노출해서도 안되기 떄문에 먼저 password를 write_only로 설정하면 Serializer에서 나타나지 않게 됩니다.
그리고 장고에서는 password를 반드시 set_password()함수를 통해서 암호화 해서 저장을 해야만합니다.
그래서 ModelSerializer에서 cretate()함수를 오버라이딩해서 validate에서 password를 바꿔주고 저장을 해야 하는 것이죠
user = super().create(validated_data) 를 하면 instance가 반환되는데 그 인스턴스에 setpassword를 하는 개념이라고 보시면 됩니다.
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = (
"id",
"username",
"first_name",
"last_name",
"email",
"avatar",
"superhost",
"password",
)
read_only_fields = ("id","superhost","avatar")
def create(self, validated_data):
password = validated_data.get("password")
user = super().create(validated_data)
user.set_password(password)
user.save()
return user
그럼 내일은 로그인 JWT에 대해서 알아보도록 하겠습니다.
'프로그래밍 > Django개발(MAC OS)' 카테고리의 다른 글
Django Rest API 서버 만들기 요약 - Day 5 (Filter, Dynamic_filed) (0) | 2022.05.11 |
---|---|
Django Rest API 서버 만들기 요약 - Day 4 : 로그인 JWT (0) | 2022.05.11 |
Django Rest API 서버 만들기 요약 - Day 2 (0) | 2022.05.10 |
Django Rest API 서버 만들기 요약 - Day 2 (0) | 2022.05.09 |
Django Rest API 서버 만들기 요약 - Day 1 (0) | 2022.05.08 |