Django drf(django rest framework)

이민기·2022년 6월 20일
0
post-thumbnail

django rest framework

  • 기존 django에서 확장된 기능들을 이용할 수 있음
  • 대표적으로 drf에서 사용 가능 한 Serializer라는 것이 존재
  • 실제로 django 백엔드 개발자를 채용 할 때 drf 경험을 보는 회사들이 많음

- drf 설치하기

pip install django

pip install djangorestframework

- http status code에 대한 이해

- 2xx : normal
- 3xx : redirect
- 4xx : client error
- 5xx : server error

- http method 종류

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

POST / PUT / DELETE 통신 시 csrf error가 발생 할 때

  • test 코드에 추가
var xsrfCookie = postman.getResponseCookie("csrftoken");
postman.setGlobalVariable('csrftoken', xsrfCookie.value);

Headers에 Key / Value 추가

  • Key : X-CSRFToken
  • Value : {{csrftoken}}

queryset, object의 차이에 대한 이해

- object : 테이블에 입력 된 특정 레코드
- queryset : object의 집합 ex) `[object(1), object(2), object(3)]`

데이터 추가, 조회, 삭제, 수정하기

# 추가1
model = Model(
  field1="value1",
  field2="value2"
)
model.save()

# 추가2
Model.objects.create(
  field1="value1",
  field2="value2"
)

# 조회
Model.objects.all()
Model.objects.filter()
Model.objects.get()

# 수정1
model = Model.object.get(id=obj_id)
model.field = value
model.save()

# 수정2
Model.objects.filter(field__contains=value).update(
    field1="value1",
    field2="value2"
)

# 삭제
Model.objects.filter(field="value").delete()
Model.objects.get(id=obj_id).delete()

자주 사용하는 패턴 모음

# 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

ustom user 생성 및 사용자 로그인 구현

  • 일반 user model은 필드가 고정되어 있어 커스텀이 어려움
  • custom user model 생성 시 필드들을 자유롭게 커스텀 가능

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

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

settings.py

AUTH_USER_MODEL = 'user.User' # app.table 형태

views.py

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)
        if not user:
            return Response({"error": "존재하지 않는 계정이거나 패스워드가 일치하지 않습니다."}, status=status.HTTP_401_UNAUTHORIZED)

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

settings.py 자주 사용하는 설정

  • debug = True / False debug 모드 설정. static file 처리, allow host, 에러 페이지 등의 설정이 달라진다.
  • LANGUAGE_CODE = 'ko-kr' : 언어 설정
  • TIME_ZONE = 'Asia/Seoul' : Timezone 설정
  • DATABASES : DB 설정
  • INSTALLED_APPS : 사용할 앱 설정
profile
지나가는사람

0개의 댓글