django
확장 가능한 json 형식
익숙하게 사용했던 패턴이지만 표준인 줄 모르고 넘어갔던 내용을 스프링의 API 작성을 공부하던 중에 다시 보게되어 확실히 정리하기위해 포스팅함 Django의 Serailizer에 many=True 옵션을 주는 경우 + Spring에서 @RestController를 사용해 Entity를 그대로 반환하는 경우 API의 response를 보면 아래와 같이 []배열 형태로 Json이 반환된다. [ { "id": 1, "name": "newhello", "address": null, "orders": [] }, { "id": 2, "name": "member1", "address": { "city": "서울", "street": "test", "zipcode": "1234" }, "orders": [] }, { ..
[Django] ModelViewSet에서 Retrieve의 동작 원리
APIView를 상속받는.. GenericAPIView를 상속받는.. GenericViewSet을 상속받는.. ModelViewSet은 mixins를 모두 상속받는다. 3단 추상화 .... Retrieve란? mixinx.RetrieveModelsMixin에 구현되어있는 메서드이다. 찾고자 하는 모델의 세부 정보를 반환한다. 어떻게 찾고자 하는 모델을 알 수 있을까? 우선 RESTful 규칙에 지키며 통신이 이루어진다고 가정하자. [GET] http://localhost/post/3 위와 같은 url은 id가 3인 post를 요청하는 것이다. 해당 url을 받아들일 수 있는 django의 urls.py를 보면 urlpatterns = [ path('post/', ...), ] 이런 식으로 되어있을 것이다..
[Django] Serializer와 validate (TIP!)
POST method로 새로운 글을 만들 때는 제목이 중복되면 안된다. 중복되면 안되는 필드가 있다고 생각하면 된다. 하지만 해당 글을 수정하고 저장할 때의 제목 중복여부는 수정 이전의 제목과 같을때만 허용해야 할 것이다. serailizer에서 중복을 허용하지 않기 위해서 다음과 같은 간단한 유효성 검사 메서드를 만들 수 있다. def validate(self, attrs): if Category.objects.filter(title=attrs['title']).exists(): raise ValidationError(_("Duplicated title.")) return super().validate(attrs) 여기서 validate는 serializer.is_valid()가 호출이 되면 실행이되는..
[Django] DRF 구조 이해 #1 (APIView)
APIView는 DRF에서 사용하는 GenericAPIView, Viewset과 같이 편리하게 사용할 수 있는 api 라이브러리들의 기반이 되는 클래스이다. 참고:) APIView 클래스 전체 더보기 class APIView(View): # The following policies may be set at either globally, or per-view. renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES parser_classes = api_settings.DEFAULT_PARSER_CLASSES authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES throttle_classes ..
[Django] django 기본 인증 시스템 커스텀(아이디, 이메일 로그인)
AUTHENTICATION_BACKENDS = ( 'django.contrib.auth.backends.ModelBackend', ) Django의 기본 인증시스템은 django.contrib.auth.backends.ModelBackend 를 사용한다. django session 기반의 인증 시스템이다. jwt인증을 구현했다고 하더라도 admin 페이지에서는 계속 기본 인증시스템을 사용한다. 인터넷을 사용하다 보면 사이트마다 로그인하는 방식이 다르다. 이메일 형식의 아이디 입력. 일반 단어 형식의 아이디 입력. 소셜 로그인 기타.. 처음에 회원가입을 할 때 아이디와 이메일을 모두 입력한다고 가정하자. 이때 아이디로도 로그인이 가능하고, 이메일로도 로그인이 가능하게 만들어보자. ## auth/authen..
[Django] DRF를 사용한 JWT Authentication #2
이번 포스팅에서는 JWT를 생성하고 로그인,로그아웃 기능을 구현하는 방법을 정리해 보려고 한다. 로그인 로직 클라이언트는 LoginApi를 호출하면서 {"username": "이름", "password": "비번"} 정보를 전달해준다. 서버는 username과 password를 가지고, 해당하는 유저를 찾은 다음 jwt_login을 수행한다. jwt_login에서는 access_token과 refresh_token을 생성한다. 생성된 access_token은 {"access_token": access_token}형태의 json으로 클라이언트에 전달되고, 생성된 refresh_token은 httpOnly=True 속성을 가진채로 cookie에 삽입된다. 로그아웃 로직 클라이언트에서 LogoutApi를 호출..
[Django] DRF를 사용한 JWT Authentication #1
이번 포스팅에서는 DRF를 사용해 JWT 인증시스템을 어떻게 구현하는지에 대해서 정리해보려고 한다. JWT란? JWT는 Json Web Token의 약자로 모바일이나 웹의 사용자 인증을 위해 사용하는 암호화된 토큰을 의미한다. JWT 정보(사용자 id, 토큰 생성시간, 만료시간)를 request에 담아 사용자의 정보 열람, 수정 등 개인적인 작업들을 수행할 수 있다. JWT를 사용해 인증시스템을 구축한 이유 1. 프론트엔드와 백엔드의 완전한 분리 Django의 세션기반 로그인을 사용하기 위해서는 Django Template을 사용해야한다. 이는 프론트엔드 개발인원들이 반드시 Django의 문법을 어느 정도 이해해야만 페이지를 구성할 수 있다는 뜻이다. 하지만 JWT를 사용한다면 클라이언트와 서버의 완전한..
[Django] django-debug-toolbar 안보임 오류 해결
degub-toolbar가 왜 안 나오는지 도저히 모르겠다면 꼭 해보세요. import mimetypes mimetypes.add_type("application/javascript", ".js", True) 위 코드를 settings.py가 있는 폴더의 urls.py에 추가해보자. from django.contrib import admin from django.conf import settings from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), ... ] import mimetypes mimetypes.add_type("application/javascript", ".js", True) if se..
[Django] DataFrame to CSV (download)
개요 1. Django에서 DB의 data를 추출해서 DataFrame으로 만든다. 2. 만들어진 DataFrame을 한글파일명을 가진 csv파일로 변환해서 내보낸다. dataframe to csv를 수행할 정보에 대해 아주 간단하게 요약한 class 다이어그램이다. Question이 다수 있을 것이고, 지원자들은 특정 Question에 대해서 Answer를 남길 것이다. 지원일자 이름 생년월일 Question1.content Question2.content ... 0 2021-10-11 23:56:23 김 1998.09.09 ~~ ** ... 1 2021-10-13 13:54:11 이 1999.09.09 %% ## .... 2 2021-10-14 08:10:45 박 2000.09.09 && @@ .....
[Djnago] Django 이메일 인증하기(Thread)
비밀번호를 찾기 위해서 가입 했던 이메일로 인증번호을 보내는 기능에 대한 설명 ## users/apis.py class SendPasswordEmailApi(PublicApiMixin, APIView): def post(self, request, *args, **kwargs): """ 비밀번호 변경 인증 코드 발송 """ target_username = request.data.get('username', '') target_email = request.data.get('email', '') target_user = User.objects.filter( username=target_username, email=target_email ) if target_user.exists(): auth_string = ..