컴퓨터/WEB

[Django] 장고 User 모델 OneToOneField로 확장해서 사용하기 + 토큰으로 로그인하기

정석이 2022. 5. 14. 01:44

 

장고에서는 User모델을 제공해준다.

 

 

https://docs.djangoproject.com/en/4.0/ref/contrib/auth/

 

django.contrib.auth | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

 

 

자세한 필드 내용은 저 공식문서를 보면 된다.

 

보통 많이 쓰는게 username, password, email 정도?

 

 

그런데 나는 회원가입을 시도할 때 다른 내용도 넣어줘야 했기 때문에 저 User 모델과 다른 모델을 OneToOneField로 연결해서 사용할 것이다.

 

 

OneToOneField는 1:1 관계에서 사용한다. 유저 하나당 1개의 모델을 참조할 것이므로... onetoone을 사용했다.

 

 

 

 


 

 

models.py

 

from django.db import models
from django.contrib.auth.models import User


class Profile(models.Model): # 한 유저당 1개의 프로필을 가지므로 oneTooneField 사용
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='users') # CASCADE 쓰면 delete 할 때 이 오브젝트를 참조하는 오브젝트도 같이 삭제
    nickname = models.CharField(max_length=20) # 한글은 5글자까지 가능
    height = models.IntegerField(blank=False)
    weight = models.IntegerField(blank=False)
    age = models.IntegerField(blank=False)
    sex = models.IntegerField(blank=False)
    pa = models.IntegerField(blank=False)

 

 

user라는 값을 OneToOneField로 연결했다.

 

User 모델을 참조했기 때문에 변수명 user로 해줘야한다. 안그럼 꼬이고 꼬여서 에러날 수 있음

 

 

 

 

 

urls.py (app 안에 있는 urls.py)

 

from django.urls import path, include
from . import views

app_name = 'user'

urlpatterns = [
    path('signup/', views.SignupView.as_view()), # 클래스뷰라서 as_view()사용
    path('login/', views.LoginView.as_view()),
]

 

 

 

 

views.py

 

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from . import models

 

 

- 회원가입

class SignupView(APIView): # 회원가입
    def post(self, request):
        # DB검사
        if User.objects.filter(username=request.data['id']).exists():
            return Response({"message": "fail"}, status = status.HTTP_403_FORBIDDEN)
        
        user = User.objects.create_user(username=request.data['id'], password=request.data['password'])
        profile = models.Profile(
            user=user, # onetoonefield라서 User모델 row 자체를 넣어줘야함
            nickname=request.data['nickname'], 
            height=request.data['height'],
            weight=request.data['weight'],
            age=request.data['age'],
            sex=request.data['sex'],
            pa=request.data['pa']
        )

        user.save()
        profile.save()

        return Response({"message": "success"})

 

 

- 로그인

class LoginView(APIView): # 로그인
    def post(self, request):
        user = authenticate(username=request.data['id'], password=request.data['password'])
        # authenticate도 장고에서 제공해줌

        if user is not None:
            token, created = Token.objects.get_or_create(user=user)
            return Response({"token": token.key})
        else:
            return Response({"message": "fail"}, status = status.HTTP_403_FORBIDDEN)

 

 

 

로그인할 때 토큰이 만들어진다.

 

 

이걸로 웹 페이지 돌아다닐 때 사용할거임