Permissions
기본 permissions
permissions.AllowAny : 모든 사용자를 대상으로 접근 허용
permissions.IsAuthenticated : 로그인 된 사용자를 대상으로 접근 허용
permission class 커스텀하기
# DRF_study/permissions.py
from rest_framework.permissions import BasePermission
from datetime import timedelta
from django.utils import timezone
from rest_framework.exceptions import APIException
from rest_framework import status
# BasePermission 상속 필수!
class RegistedMoreThan3MinsUser(BasePermission):
# False 리턴 시 보여주는 메세지
message = '가입 후 3분 이상 지난 사용자만 사용하실 수 있습니다.'
# has_permission 오버라이딩
def has_permission(self, request, view):
user = request.user
# 로그인 한 사용자에 대해서만 허가 ex) 조회
if request.method == "GET" and user.is_authenticated:
return True
# 가입 후 3분이 지난 사용자만 허가 ex) 글쓰기 권한
elif request.method == "POST" and
bool(request.user and request.user.join_date < (timezone.now() - timedelta(days=3))):
return True
# admin의 경우 허가
elif user.is_admin:
return True
return False
# is_authenticated 값이 없을 경우 발생 시킬 예외 정의
class GenericAPIException(APIException):
def __init__(self, status_code, detail=None, code=None):
self.status_code=status_code
super().__init__(detail=detail, code=code)
class IsAdminOrIsAuthenticatedReadOnly(BasePermission):
# 메서드 지정을 통해서도 세부적인 권한 조절 가능
SAFE_METHODS = ('GET', )
# return 값 False 일 때 전달할 메세지
message = '접근 권한이 없습니다.'
def has_permission(self, request, view):
user = request.user
# 먼저 로그인 되어있지 않은 것을 판별해서 예외 처리해야만한다 하지않을 경우
# 로그인되어있지 않다는 오류가 메세지로 나오고 접근 권한에 대해서는 판별도 되지 않게 됨
if not user.is_authenticated:
response ={
"detail": "서비스를 이용하기 위해 로그인 해주세요.",
}
raise GenericAPIException(status_code=status.HTTP_401_UNAUTHORIZED, detail=response)
# 로그인 ok, admin ok
if user.is_authenticated and user.is_admin:
return True
# 로그인 ok, method==GET ok,
elif user.is_authenticated and request.method in self.SAFE_METHODS:
return True
return False
view에서 permission선언할 때에 permission_classes 변수에 정확히 오버라이딩해야한다. 실수로 permissions_classes 로 적어서 전혀 작동하지 않았었는데.. 다행히도 팀원들과 같이보면서 이부분을 발견하게 되었다. framework 를 사용하는 거다보니 아무래도 오버라이딩을 해서 쓰는 경우이다보니 오타에 주의해야하겠다.
...
from DRF_study.permissions import RegistedMoreThan3MinsUser
class ArticleView(APIView):
# permissions_classes (x) permission_classes (o)
permission_classes = [RegistedMoreThan3MinsUser]
def get(self, request):
...
django admin 페이지 심화
# DRF_study/admin.py
from django.contrib import admin
from blog.models import *
from user.models import *
# Register your models here.
class UserProfileInline(admin.StackedInline):
'''
StackedInline : 세로 정렬
TabulraInline : 가로 정렬
'''
model = UserProfile
# 취미 선택 및 구분 하기 좋게 창 구분 지어줌
filter_horizontal = ['hobby']
class UserAdmin(admin.ModelAdmin):
list_display = ('id', 'username', 'fullname', 'email') #목록에 표시할 필드
list_display_links = ('username', 'fullname' ) # 클릭 가능하게 하는 것
search_fields = ('username', ) # 검색 기준
readonly_fields = ('username', 'join_date', ) # 읽기전용 필드
# 상세 내용 목차별로 출력할 필드
fieldsets = (
("info", {'fields': ('username', 'fullname','email', 'join_date')}),
('permissions', {'fields': ('is_admin', 'is_active', )}),
)
# obj에는 목록에서 클릭한 object의 값이 들어감
def get_readonly_fields(self, request, obj=None):
if obj:
return('username', 'join_date', )
else:
return('join_date', )
# 다른 테이블이지만 상세 내용에 표시할 정보(역참조관계여야함!)
inlines = (
UserProfileInline,
)
def has_add_permission(self, request, obj=None): # 추가 권한
return True
def has_delete_permission(self, request, obj=None): # 삭제 권한
return True
def has_change_permission(self, request, obj=None): # 수정 권한
return True
admin.site.register(User, UserAdmin)
admin.site.register(UserProfile)
admin.site.register(Category)
admin.site.register(Article)
admin.site.register(Hobbies)
admin.site.register(Comment)
ORM심화
__ 두개를 쓰는 때는 심화쿼리문을 찾을 때나 외래키를 찾을 때 사용됨
ex) user__fullname > user를 타고 들어가서 fullname을 검색하게됨
search_user = request.data.get("search_user", "")
AritcleModel.objects.filter(user__fullname__contains=search_user)
contains : 특정 String이 포함된 object 찾기
endwith, startwith : 특정 String으로 시작/끝나는 object 찾기
gt(>), lt(<), gte(>=), lte(<=) : 특정 값끼리들 비교
ex) filter(age__gte=19), filter(join_date__lte=
in : 특정 list에 포함된 object 찾기
field lookups에서 다양한 추가 기능들이 있다.
serializer 보낼 때 context= key value 형태로 원하는 데이터를 넘길 수 있음
Q 를 명시적으로 달아줌으로서 쿼리에 and, or를 적용할 수 있다.
쿼리문 처럼 | , & 쓰는 것
Article.objects.filter(
Q(title__contains=title) |
Q(content__contains=content)
)
'회고록(TIL&WIL)' 카테고리의 다른 글
TIL 2022.06.24 DRF/ User관련 구현, Article관련 구현, 특강 숙제 (0) | 2022.06.24 |
---|---|
TIL 2022.06.23 머신러닝 특강 (0) | 2022.06.23 |
WIL 2022.06.20 DRF/ Custom User, login/out, 역참조, Serializer (0) | 2022.06.21 |
WIL 2022.06.20 DRF/ venv환경 구성, 모델링옵션, REST API, POSTMAN, ORM (0) | 2022.06.20 |
TIL 2022.06.15 django 특강, TODAY_LUNCH Project Refectoring (0) | 2022.06.15 |