본문 바로가기
FrameWork/Django

Permission Classes

by mansoorrr 2024. 7. 22.

Rest API 설계시 대표적으로 CRUD를 언급한다.

그래서 사용하는 request method는 4개이다. (GET, POST, PUT, DELETE)

 

어떤  홈페이지를 만들려고 한다면 GET은 조회하는 매서드이므로 꼭 로그인(인증)된 사람만 데이터를 볼 수 있지는 않다.

하지만 POST(생성), PUT(수정), DELETE(삭제)는 인증된 사람만 가능해야 한다.

 

이것을 구현하기 위해 django에서는 조건문과 request.user.is_authenticated와 PermissionDenied를 이용해 인증된 사람만 수행 가능하도록 할 수 있다. 하지만 매번 이렇게 하는 것은 충분히 귀찮으므로 permission_classes라는 것을 통해 조건문으로 구현하던 것을 대체한다.

 

 

[** Permission Classes **]

  • rest_framework.permissions.IsAuthenticated, IsAuthenticateOrReadOnly
    • IsAuthenticated: GET, POST, PUT, DELETE모두 인증시에만 작동
    • IsAuthenticateOrReadOnly : GET을 제외한 나머지 매서드들은 인증시에만 작동
  • 클래스 안에 permission_classes = [IsAuthenticated or IsAuthenticateOrReadOnly ]
from rest_framework.permissions import IsAuthenticatedOrReadOnly

class Rooms(APIView):
	#인증 적용
     permission_classes = [IsAuthenticatedOrReadOnly]  
     
     def post(self, request):          
          #permission_classes를 적용했으므로 request.user.is_authenticated 삭제
          #if request.user.is_authenticated: 
               data = request.data
               serializer = RoomDetailSerializer(data=data)
               #유효성검사
               if serializer.is_valid() == False:
                    return Response(serializer.errors)
               #category
               category_pk = data.get('category') #데이터 받기
               if not category_pk: #입력 안되어있을경우 에러
                    raise ParseError('Category is required')
               try:
                    category = Category.objects.get(pk=category_pk) #찾기
                    #찾은 카테고리가 rooms가 아닌 경우 에러
                    if category.kind == Category.CategoryKindChoice.EXPERIENCES:
                         raise ParseError('Category Type should be rooms')
               except Category.DoesNotExist: #없을때 에러반환
                    raise ParseError('Category Does not exist')
               #트랜잭션 실행: 오류나면 room저장 안함
               try:
                    with transaction.atomic():
                         new_room = serializer.save(
                              owner = request.user, #user 추가
                              category = category #category 추가
                         )
                         #amenities: 이거 없어도 일단 방은 추가 가능
                         amenities = data.get('amenities')
                         for amenity_pk in amenities:                         
                              amenity = Amenity.objects.get(pk=amenity_pk) #찾기
                              new_room.amenities.add(amenity) #new_room에 추가
                         return Response(RoomDetailSerializer(new_room).data)
               except Exception:
                    raise ParseError('Amenity not found')
          #else:
          #    raise Response(status=NotAuthenticated)

 

 

'FrameWork > Django' 카테고리의 다른 글

Test  (0) 2024.07.26
Authentication  (0) 2024.07.25
File Upload  (0) 2024.07.21
Pagination  (0) 2024.07.21
DB transaction  (0) 2024.07.20