내일배움캠프 - DRF 4일차 개발일지

Dongwoo Kim·2022년 6월 21일
0

내일배움캠프 - DRF

목록 보기
6/12

스파르타 코딩클럽

내일배움캠프 AI 웹개발자양성과정 2회차

DRF 4일차 개발일지

0. 강의요약

  • user admin 생성
  • admin 심화
  • permission class 심화
  • gte, lte 등 다양한 field lookup 활용 및 정렬

1. user admin 생성

1) BaseUserAdmin

: admin 페이지에서 유저를 생성하기위해 필요 (password가 해싱된 값으로 저장됨)

# user/admin.py
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

class UserAdmin(BaseUserAdmin):
    list_display = ('id', 'username', 'fullname', 'email')
    list_display_links = ('username', )
    list_filter = ('username', )
    search_fields = ('username', 'email', )

    fieldsets = (
        ("info", {'fields': ('username', 'password', 'email', 'fullname', 'join_date',)}),
        ('Permissions', {'fields': ('is_admin', 'is_active', )}),)

    filter_horizontal = []

    def get_readonly_fields(self, request, obj=None):
        if obj:
            return ('username', 'join_date', )
        else:
            return ('join_date', )
          
admin.site.register(User, UserAdmin)

2. admin 심화

1) Tabulainline / Stackinline 설정

: 역참조된 object를 보여줄 수 있음

  • Tabulainline : attribute를 가로로 배치
  • Stackinline : attribute를 세로로 배치
# user/admin.py
# 사용 방법은 TabulaInline과 StackedInline 모두 동일
# 둘 다 사용해보고 뭐가 좋은지 비교해보기
# class UserProfileInline(admin.TabularInline):
class UserProfileInline(admin.StackedInline):
    model = UserProfile

class UserAdmin(admin.ModelAdmin):
	...
    inlines = (
            UserProfileInline,
        )

2) 권한 설정

: admin 페이지에서 해당 object에 대한 수정/생성/삭제 권한 설정 가능

# user/admin.py
class UserAdmin(admin.ModelAdmin):
	...
	def has_add_permission(self, request, obj=None): # 추가 권한
        return False

    def has_delete_permission(self, request, obj=None): # 삭제 권한
        return False

    def has_change_permission(self, request, obj=None): # 수정 권한
        return False

3. permission class 심화

: method 별로 permission 설정 가능

# permissions.py
from rest_framework.permissions import BasePermission
from rest_framework.exceptions import APIException
from rest_framework import status

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):
    """
    admin 사용자는 모두 가능, 로그인 사용자는 조회만 가능
    """
    SAFE_METHODS = ('GET', )
    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)

        if user.is_authenticated and user.is_admin:
            return True
            
        if user.is_authenticated and request.method in self.SAFE_METHODS:
            return True
        
        return False

4. gte, lte 등 다양한 field lookup 활용 및 정렬

1) contains

: 특정 string이 포함된 object 찾기

# fullname에 "이름"이라는 string이 포함된 사용자들을 찾는다.
UserModel.objects.filter(fullname__contains="이름")

2) startswith / endswith

: 특정 string으로 시작하는/끝나는 object 찾기

# email이 "@naver.com"으로 끝나는 사용자들을 찾는다.
UserModel.objects.filter(email__endswith="@naver.com")

3) gt / lt / gte / lte

: 특정 값보다 크거나/작거나/크거나같거나/작거나같은 object 찾기

# 사용자 프로필의 나이가 19 이상인 사용자들을 찾는다.
UserProfileModel.objects.filter(age__gte=19)

4) in

: 특정 list에 포함된 object 찾기

# 사용자 프로필의 운동 혹은 독서를 취미로 가진 사용자들을 찾는다.
UserProfileModel.objects.filter(hobby__name__in=["운동", "독서"])

5) 기타 Field lookups

https://docs.djangoproject.com/en/4.0/ref/models/querysets/#field-lookups

6) order_by

: queryset을 정렬하여 가져오기

User.objects.all().order_by("join_date") # 가입일 순 정렬
User.objects.all().order_by("-join_date") # 가입일 역순 정렬
User.objects.all().order_by("?") # 랜덤 셔플

7) Q

from django.db.models.query_utils import Q

class UserView(APIView)
    def get(self, request):
        # 취미 중 산책이 있거나 나이가 19살보다 많고 김씨인 사람만 필터 사람만 필터
        qyery = Q(hobby__name="산책") | Q(age__gt=19, user__name__startswith="김")

        # 취미 중 산책이 있으면서 나이가 19살보다 많은 사람만 필터
        qyery = Q(hobby__name="산책") & Q(age__gt=19)				
        user_profile_list = UserProfileModel.objects.filter(qyery)
profile
kimphysicsman

0개의 댓글