AI 웹 개발 과정/DRF 특강

DRF 특강 | 2일차

만 기 2022. 6. 16. 09:13

 

Views.py 에서 request 처리

 

1. FBV 또는 CBV 형식

FBV : Function Base View

CBV : Class Base View

둘다 잘 활용할줄 알아야하지만 CBV 를 더 많이 쓴다

 

 

2. APIView : CBV로 정의 됨. APIView 를 상속받은 클래스 안에 request method에 맞는 함수들을 정의해주면 각각의 요청은 request method 이름에 맞게 구분되어 그에 맞는 결과를 반환한다. (ex : post 요청은 post 함수로)

 

3. REST API

- http method 종류

  • get : 조회
  • post : 생성
  • put : 수정
  • delete : 삭제

 - 참조 : https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html

 

 

4. permission : 요청에 대한 액세스 권한 부여 여부

 

 

5. request : 요청을 파싱

request.POST  # 폼 데이터만 다루며, 'POST' 메서드에서만 사용 가능
request.data  # 아무 데이터나 다룰 수 있고, 'POST'뿐만 아니라 'PUT'과 'PATCH' 메서드에서도 사용 가능

 

6. Response

Response(data, status=None, template_name=None, headers=None, content_type=None)

  • data: 응답에 대한 직렬화된 데이터입니다.
  • status: 응답에 대한 상태 코드입니다. 기본값은 200 입니다. 상태 코드 도 참조하십시오 .
  • template_nameHTMLRenderer: 선택된 경우 사용할 템플릿 이름 입니다.
  • headers: 응답에 사용할 HTTP 헤더 사전입니다.
  • content_type: 응답의 콘텐츠 유형입니다. 일반적으로 이것은 콘텐츠 협상에 의해 결정된 대로 렌더러에 의해 자동으로 설정되지만 콘텐츠 유형을 명시적으로 지정해야 하는 경우가 있을 수 있습니다.

 

7. 예시

- user/views.py

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework import permissions  # 권한 설정
from rest_framework.response import Response
# 
# Create your views here.
class UserView(APIView):
    permission_classes = [permissions.AllowAny] # 모두 허용
    # permission_classes = [permissions.IsAuthenticated] # 로그인된 사용자만
    # permission_classes = [permissions.IsAdminUser] # 관리자만
    # 사용자 정보 조회
    def get(self, request):
        return Response({'message':'get method!!'})
    
    # 회원 가입
    def post(self, request):
        return Response({'message':'post method!!'})
    
    # 회원 정보 수정
    def put(self, request):
        return Response({'message':'put method!!'})
    
    # 회원 탈퇴
    def delete(self, request):
        return Response({'message':'delete method!!'})

 

- urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('user/', include('user.urls'))
]

 

- user/urls.py

from django.contrib import admin
from django.urls import path, include
from user import views

urlpatterns = [
    # user/     # CBV 는 .as_view() 추가해줘야함
    path('', views.UserView.as_view())
]

 

 

포스트맨을 이용해서 response 받기

- user/views.py

def sum(num1, num2):
    return num1+num2

# Create your views here.
class UserView(APIView):
    permission_classes = [permissions.AllowAny] # 모두 허용
    # 사용자 정보 조회
    def get(self, request):
        result = sum(**request.data)
        return Response({'message':f'result num is {result}!!'})

 

- postman

 

  • POST / PUT / DELETE 통신 시 csrf error가 발생 할 때
    • Tests에 코드 추가
    • var xsrfCookie = postman.getResponseCookie("csrftoken");
      postman.setGlobalVariable('csrftoken', xsrfCookie.value);
    • Headers에 Key / Value 추가
      • Key : X-CSRFToken
      • Value : {{csrftoken}}

 

 

자주 사용되는 패턴

# objects.get에서 객체가 존재하지 않을 경우 DoesNotExist Exception 발생
try:
    Model.objects.get(id=obj_id)
except Model.DoesNotExist:
    # some event
    return Response("존재하지 않는 오브젝트입니다.")

# -join_date처럼 "-"를 붙이면 역순으로 정렬
# .order_by("?")사용시 무작위 셔플
Model.objects.all().order_by("join_date") 

# queryset에서 첫번째 object를 가져옴. all()[0]과 동일
Model.objects.all().first()

# 입력한 object가 존재 할 경우 해당 object를 가져오고, 존재하지 않을 경우 새로 생성
object, created = Model.objects.get_or_create(
    field1="value1",
    field2="value2",
)

if created: 
    # created event
else: 
    # already exist event

 

 

 

custom user 모델 

custom user model 생성 시 필드들을 자유롭게 커스텀 가능

 

- import

from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

 

BaseUserManager  : User를 생성할때 사용

AbstractBaseUser  : 상속받아 생성하는 클래스

 

user/models.py 작성

from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

# custom user model 사용 시 UserManager 클래스와 create_user, create_superuser 함수가 정의되어 있어야 함
class UserManager(BaseUserManager):
    def create_user(self, username, password=None):
        if not username:
            raise ValueError('Users must have an username')
        user = self.model(
            username=username,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user
    
    # python manage.py createsuperuser 사용 시 해당 함수가 사용됨
    def create_superuser(self, username, password=None):
        user = self.create_user(
            username=username,
            password=password
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

# AbstractBaseUser 상속
class User(AbstractBaseUser):
    username = models.CharField("사용자 계정", max_length=20, unique=True)
    email = models.EmailField("이메일 주소", max_length=100)
    password = models.CharField("비밀번호", max_length=128)
    fullname = models.CharField("이름", max_length=20)
    join_date = models.DateTimeField("가입일", auto_now_add=True)

		# is_active가 False일 경우 계정이 비활성화됨
    is_active = models.BooleanField(default=True) 

    # is_staff에서 해당 값 사용
    is_admin = models.BooleanField(default=False)
    
    # id로 사용 할 필드 지정.
    # 로그인 시 USERNAME_FIELD에 설정 된 필드와 password가 사용된다.
    USERNAME_FIELD = 'username'

    # user를 생성할 때 입력받은 필드 지정
    REQUIRED_FIELDS = []
    
    objects = UserManager() # custom user 생성 시 필요
    
    def __str__(self):
        return self.username

    # 로그인 사용자의 특정 테이블의 crud 권한을 설정, perm table의 crud 권한이 들어간다.
    # admin일 경우 항상 True, 비활성 사용자(is_active=False)의 경우 항상 False
    def has_perm(self, perm, obj=None):
        return True
    
    # 로그인 사용자의 특정 app에 접근 가능 여부를 설정, app_label에는 app 이름이 들어간다.
    # admin일 경우 항상 True, 비활성 사용자(is_active=False)의 경우 항상 False
    def has_module_perms(self, app_label): 
        return True
    
    # admin 권한 설정
    @property
    def is_staff(self): 
        return self.is_admin

UserManager 클래스에 2가지 함수 

  1. create_user() : User 생성하는 함수
  2. create_superuser() : 관리자 User 생성하는 함수

 

 

settings.py 에 추가

# custom 모델 user앱 안의 User 모델 사용
AUTH_USER_MODEL = 'user.User'

user/models.py의 User 모델 속성 추가

user/models.py에 UserManager 추가

 

 

 

로그인 기능 구현

login , authenticate 임포트 하여 사용

from django.contrib.auth import login, authenticate

class UserApiView(APIView):
    # 로그인
    def post(self, request):
        username = request.data.get('username', '')
        password = request.data.get('password', '')

        user = authenticate(request, username=username, password=password)
        # user = authenticate(request, **request.data)
        
        if not user:
            return Response({"error": "존재하지 않는 계정이거나 패스워드가 일치하지 않습니다."}, status=status.HTTP_401_UNAUTHORIZED)

        login(request, user)
        return Response({"message": "로그인 성공!!"}, status=status.HTTP_200_OK)

 

 

 

'AI 웹 개발 과정 > DRF 특강' 카테고리의 다른 글

DRF 복습 퀴즈  (1) 2022.06.23
DRF 특강 | 5일차  (0) 2022.06.21
DRF 특강 | 4일차  (0) 2022.06.20
DRF 특강 | 3일차  (0) 2022.06.17
DRF 특강 | 1일차  (0) 2022.06.15