[drf]airbnb-api -13 Create account

Hyeseong·2021년 3월 26일
0
post-thumbnail

이제 계정 생성을 위한 API를 만들어 보도록 하조.

만들었던 Serializers들~

아래 3개 정도 만들 었어쥬?!

  1. WriteUserSerializer
class WriteUserSerializer(serializers.ModelSerializer): 
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email') # Profile을 변경할때 사용할 API에 사용

    def validate_first_name(self, value):
        print(value)
        return value.upper()
  1. RelatedUserSerializer
class RelatedUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = (
            'username',
            'first_name',
            'last_name',
            'email',
            'avatar',
            'superhost',
        )
  1. ReadUserSerializer
class ReadUserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        exclude = (
            'groups',
            'user_permissions',
            'password',
            'last_login',
            'is_superuser',
            'is_staff',
            'is_active',
            'favs',
            'date_joined',)

여기서 Related~~ 시리얼라이저는 RoomSerializer에서 중첩 시리얼라이저로 사용해서 데이터를 일부 뿌려주는 역할로 사용하고 있습니다.

그럼 나머지 Read~, Write 시리얼라이저 2개는 중복된 역활이 상당하기에 하나로 합체 할게요.

시리얼라이저 이름은 포괄적으로 UserSerializer로 만들고요.

반드시 read_only_fields를 적어주세요.
또한 비밀번호는 보안을 위해서 보여주면 안되요~ 그래서 별도로 CharField로 메타클래스의 fields 변수의 내부 문자열 'password'와 동일하게 password라고 UserSerializer의 멤버변수로 정의내려줍니다.
여기서 핵!심!은 write_only플래그!를 트루!로 써줘야합니다.

그럼 비밀번호는 입력은 했지만 반환된 값에는 비밀번호가 보이지 않게 되는거조.뿐만 아니라 나중에 설명하겠지만 반환된 값이 보이지 않음은 물론 비밀번호 저장시에도 필요해요.

RelatedUserSerializer, ReadUserSerializer 통합

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 validate_first_name(self, value):
        return value.upper()

그리고 나서 Views.py로 가서 기존 Related~, Read~ 시리얼 라이저 이름은 반드시 UserSerializer로 바꿔줘야합니다. 물론! 임포트!도 해주고요.

위 사진을 보면 잘 작동되는게 보이조?

content란에 이름을 변경하기 원하면 변경하길 원하는 키-벨류 쌍을 넣어서 풋! 메서드를 보내도 여전히 작동해요.


회원가입 API

users/urls.py

app_name = "users"

urlpatterns = [
    path("", views.UsersView.as_view # 추가! POST Method only
    path("me/", views.MeView.as_view()),
    path("me/favs/", views.FavsView.as_view()),
    path("<int:pk>/", views.user_detail),

users/views.py

여기서 할건 기존에 해왔던 것과 큰 차이는 없어요.

  • 시리얼라이저를 호출하는데 request.data를 키워드 아규먼트로 넘겨줘요. serializer 변수에 담아줄게요.

그런데 지난번에 partial=True를 했던 기억이 있는데 생각나나요? 그때는 하나 혹은 일부 키-벨류만 입력해서 넘겼잖아요.

그런데 지금하는건 회원가입! 즉, 지정되고 필요로하는게 일부가 아닌 전체를 다 입력해서 POST로 만들어주는겁니다. 당근 201코드를 만드는 로직을 짜야겠조.

그리고 body에 담겨져서 넘어오는 값들은 반드시 is_valid()메서드로 검증을 하고 --> save() 메서드를 통해서 저장하게되요.

만약 유효하지 않으면 400오류를 넘겨주고요.

잘보면 아래 두 개는 동일한 시리얼라이저이지만 쓰임세가 달라요. 위에꺼는 클라이언트로 받아온 JSON데이터를 파이썬 객체로 바꾸어서 이를 유효성검사를 하고 디비에 저장시키게되고요.
두번째꺼는 디비에 저장된 인스턴스를 다시 JSON으로 넘겨주기 위한 로직인거에요.

.data의 위치가 키워드인자냐? 혹은 클래스의 속성이냐에 따라 달라지네요.

  • UserSerializer(data=request.data)
  • UserSerializer(new_user).data
class UsersView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        if serializer.is_valid():
            new_user = serializer.save()
            return Response(UserSerializer(new_user).data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

browsable API를 통해서 회원가입을 하고 관리자 페이지에서 확인하면 유저가 생성된 걸 확인 할 수 있어요. 그렇지만 비밀번호가 없네요..


create()

일단 아래까지 작성하고 한번 콘솔에 찍어보조.


def create(self, validated_data):
	user = super().create(validated_data)
	print(user)

보시다 시피 비밀번호가 없네요.

위에서 확인했던 소스코인데요. 아래에 오버라이딩해서 작성하지 않으면 비밀번호가 인식되어 나타나지 않게되요.

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",
        )

비밀번호 해쉬해서 저장

사실 super().create(validated_data)가 바로 디비에 저장을 하지 않습니다. 세이브 메소드가 디비에 저장을 시키조.

그래서 포스트 메소드로 회원 가입을 시도해보면 멋지게 되는 걸 확인 할 수 있어요.

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글