Import


from django.db.models import Q, F

Q object


  • Django DB 관련 작업에서 사용할 수 있는 SQL 조건문

  • filter 메서드에서 주로 사용

  • OR이나 AND 연산자나 NOT 연산자를 사용하여 조건을 정의하기 위해 사용된다.

      Question.objects.filter(Q(subject__icontains=query) or Q(content__icontains=query))
    • 각 조건을 Q object로 만들고, 두개의 Q object를 각각 or 연산
    • or( | ), and( & ), not( ~ )

F Object

  • 쿼리 내에서 모델 필드 접근할 때 사용
  • 모델 필드나 annotated column의 값을 가져올 때 사용된다.
from django.db.models import F
Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks'))
  • 표현식과 함께 사용할 때는 반드시 유의해야 한다.
    • F 함수를 만나게 되면 캡슐화된 SQL문을 생성하기 위해 파이썬 연산자를 오버라이딩 한다.
# Tintin filed a news story!
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed += 1
reporter.save()

###############################################

from django.db.models import F

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

# reporter.refresh_from_db(fields=['stories_filed'])

reporter.name = 'Tintin Jr.'
reporter.save() # 
  • 위 소스를 아래 소스로 바꾸려고 하는건데.. 문제가 있다.
  • 아래 소스는 F('stories_filed') + 1 자체를 SQL Syntax로 만들어버려서 reporter.stories_filed의 값이 1 증가하는 쿼리가 실행된다. 이 때, reporter.stories_filed의 값을 갱신하는것이 아님. 데이터베이스 자체의 SQL문 실행
  • reporter.stories_filed 값을 실제 저장된 값으로 업데이트하기 위해선 모델을 데이터베이스에서 다시 불러와주어야 한다.
  • F Object는 save() 이후에도 모델에 남아있는 문제가 있으며, 각 save()에 적용된다. 따라서 초기 값이 1이라고 할 때, 처음 save 연산자를 해주면 SQL문이 실행되어 2가 되는데, 다음에 또 save 연산을 해주면 또 SQL문이 실행되어 3이 된다.이 과정을 해결해주기 위해서는 refresh_from_db()를 사용해주면 된다.
    • Model.refresh_from_db(using=None, fields=None)

pk

  • get을 할때, pk로 입력하나 id로 입력하나 같은 결과가 나온다.
  • pk가 id__exact와 같다고 한다.
model.objects.get(id=1)
model.objects.get(pk=1)

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] Session  (0) 2021.10.17
[ Django ] CSRFToken  (0) 2021.10.16
[ Django ] JWT(djangorestframework-simplejwt)  (0) 2021.10.15
[ Django ] JWT  (0) 2021.10.14
[ Django ] Choice  (0) 2021.09.15

전반적인 세션 개념

  • HTTP에서는 새로운 페이지를 요청할 때마다 새로운 연결하여 상태유지가 되지 않음.
  • 사용자의 상태를 유지하기 위해 쿠키와 세션 사용
    • 브라우저마다 상태 저장
  • 세션의 데이터(사용자의 데이터)는 서버에 저장된다.
  • 서버에서는 세션에 데이터를 저장하고, 세션ID를 쿠키로 클라이언트에 발급한다. (Set-cookie)
  • 클라이언트는 발급받는 세션ID를 쿠키에 저장한다.
  • https://developer.mozilla.org/ko/docs/Learn/Server-side/Django/Sessions

세션의 장점

  • 서버에 사용자의 데이터를 저장하므로 보안상 우수

세션의 단점

  • 서버에 사용자의 데이터를 저장하므로 서버의 부하 증가

Django에서의 Session


  • 세션에 데이터를 저장하기 전까지는 Sessionid를 따로 클라이언트에 전송하지 않음.
  • 세션에 데이터를 저장하는 순간부터 Sessionid를 클라이언트에 전달
  • Django에서의 세션 사용법
def f(request):
    ...
    request.session['저장할 데이터명'] = 값
  • request.session : 현재 사용자/브라우저에 대한 세션, 딕셔너리처럼 사용 가능
  • 세션에 데이터를 간접적으로 저장한 경우 따로 Django에 modified를 설정하여 데이터를 저장했음을 알려주어야 함.
    • 예를들면 session에 리스트가 저장되어 있고, 리스트의 요소중 하나의 값을 바꿧다던지..
request.session.modified = True

Session 관련 Setting 몇가지(Settings.py)


  1. SESSION_COOKIE_AGE
    • 세션 쿠키 지속기간(초), 기본값은 2주
  2. SESSION_COOKIE_HTTPONLY
    • 세션 쿠키에 HttpOnly 설정, 기본값은 True
    • 세션 쿠키를 JavaScript에서 읽는건 문제가 될 수 있으므로 False를 굳이??
  3. SESSION_COOKIE_NAME
    • 세션 쿠키의 이름, 기본값은 sessionid
  4. SESSION_COOKIE_PATH
    • 세션 쿠키의 경로, 기본값은 /
  5. SESSION_COOKIE_SECURE
    • SECURE 옵션 사용여부, https를 사용한다면 True로 하는게 좋음.
    • 기본값은 False
  6. SESSION_SAVE_EVERY_REQUEST
    • 모든 request의 session 데이터 저장
    • 원래는 session 데이터가 변경된 경우에만 저장
    • session이 텅 빈 경우는 True라 하더라도 생성되지 않음.

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] Q, F object  (0) 2021.10.20
[ Django ] CSRFToken  (0) 2021.10.16
[ Django ] JWT(djangorestframework-simplejwt)  (0) 2021.10.15
[ Django ] JWT  (0) 2021.10.14
[ Django ] Choice  (0) 2021.09.15
  • CSRF 공격을 막기 위한 방법
  • CSRF 토큰이란 다른 사이트에서 접근할 수 없는 특정 사이트에 고유한 비밀값이라고 보면 된다.
  • Django에서는 CsrfViewMiddleware에 의해 설정된다.
  • 원래는 form태그에서 {% csrf_token %} 태그를 설정
{% csrf_token %}
  • 해당 태그가 존재하는 페이지에 접속하게 되면 csrf_token이 쿠키에 추가되는것을 볼 수 있다.
  • CsrfViewMiddleware에서는 먼저, POST에 있는 csrfmiddlewaretoken을 찾고, 없다면 X-csrftoken을 찾는다.
  • X-CSRFToken의 경우는 Ajax 등 api에서 사용된다.

과정


  1. response에 set_cookie를 설정하여 csrf_token 쿠키를 넣어서 전달한다.
  2. request에서는 전달받은 csrf_token을 POST의 csrfmiddlewaretoken에 넣어서 전달하거나, 아니면 헤더에 추가한다. ⇒ X-CSRFToken에 넣어서 전달
  3. 서버에서는 쿠키에 존재하는 csrf_token의 값하고 csrfmiddlewaretoken이나 X-CSRFToken의 값을 비교하는 방식으로 진행한다.

관련 데코레이터


  • ensure_csrf_cookie 데코레이터 추가
    • csrf_token set-cookie 추가
@method_decorator(ensure_csrf_cookie)
def post(self, request, *args, **kwargs):
  • csrf_protect 데코레이터 추가
    • csrf_token 인증 진행
@method_decorator(csrf_protect)
def post(self, request, format=None):

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] Q, F object  (0) 2021.10.20
[ Django ] Session  (0) 2021.10.17
[ Django ] JWT(djangorestframework-simplejwt)  (0) 2021.10.15
[ Django ] JWT  (0) 2021.10.14
[ Django ] Choice  (0) 2021.09.15
  • 이전에는 DjangoRestFramework-jwt를 사용하였으나, 찾아보니 DjangoRestFramework-jwt가 더이상 업데이트 되지 않으며, simplejwt 사용이 권장되고 있다고 함.

설치


# 구버전 ㅂㅇ..
pip uninstall djangorestframework-jwt

# 신버전 ㅎㅇ~ 
pip install djangorestframework-simplejwt

Settings.py 설정


  • INSTALLED_APPS에 추가
INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt',
    ...
]
  • 인증방식에 JWTAuthentication 추가
REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        ...
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
    ...
}

urls.py 설정


  • TokenObtainPairView

    • POST 방식의 API
    • username, password를 넘겨주면 만약 사용자 인증이 된다면 토큰 발급
    • 기존 djangorestframework_jwt와 다르게 refresh, access 토큰이 따로 발급된다.
  • TokenRefreshView

    • POST 방식의 API
    • refresh 토큰을 넘겨주면 새로운 토큰을 발급받음.(access 토큰)
  • 여기서, 실제로 우리가 사용하게 될 토큰은 access 토큰이라고 보면 된다.

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    ...
        path('apitokenauth/', TokenObtainPairView.as_view()),
    path('apitokenrefresh/', TokenRefreshView.as_view()),
    ...
]

쿠키 설정


  • 사용자 브라우저로 하여금 쿠키를 설정하게 하기 위해선 Set-cookie 헤더를 넘겨주어야 한다.
  • response의 set_cookie 메서드를 사용하여 쿠키를 설정해 준다.
  • 예제에서는 쿠키의 키를 'JWT'로 설정하였으며 httponly를 설정하여 Script에서는 읽지 못하도록 하였음.
class TokenObtainPairView_ud(TokenObtainPairView):
    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)
        if response.status_code != 200:
            return response

        response.set_cookie(
            key = 'JWT',
            value = response.data['access'],
            max_age = 300,
            httponly = True,
            samesite = 'Lax'
        )
        return response

# urls.py는 아래로 당연히 바꾸어주어야 함.
path('apitokenauth/', TokenObtainPairView_ud.as_view()),

request → 쿠키


  • 서버에서 set_cookie 헤더가 포함된 response를 전달하면, 클라이언트에서는 키값이 'JWT'인 쿠키가 생성되어 있을 것이다.
  • 클라이언트에서 서버로 다음에 쿠키가 포함된 request를 보낼 때, 서버에서는 쿠키를 읽어서 인증하는 과정이 필요하다.
  • 따라서, 쿠키에서 JWT 토큰을 가져와서 읽고, 토큰을 검증하면 된다.
    • JWTAuthentication을 커스터마이징
class Custom_JWTAuthentication(JWTAuthentication):
    def authenticate(self, request):
        raw_token = request.COOKIES.get('JWT', None)
        if raw_token is None:
            return None

        validated_token = self.get_validated_token(raw_token)
        return self.get_user(validated_token), validated_token

class APITest(APIView):
    authentication_classes = [Custom_JWTAuthentication]

    def get(self, request, format=None):
        return Response({'message': 'success call api'})
  • set-cookie를 직접 사용해 보면서 쿠키에 대해 좀 더 알게된 것 같지만, cors 문제가 생기는 경우 브라우저에 쿠키가 설정되지 않는 문제점이 발견되었다.
    • CORS 관련 허용과 CREDENTIALS 설정을 해주어도 안되서 템플릿 자체를 서버에 넣어서 해결하긴 했으나.. 근본적인 해결책은 아닌것 같아서 조금 더 해봐야 할 것 같다.

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] Session  (0) 2021.10.17
[ Django ] CSRFToken  (0) 2021.10.16
[ Django ] JWT  (0) 2021.10.14
[ Django ] Choice  (0) 2021.09.15
[ Django ] MySQL 연동  (0) 2021.09.14

https://jwt.io/introduction

  • 로그인 시 Token 발급
  • 발급된 Token으로 서비스 이용 가능
  • JWT Web Token의 구조는 다음과 같다.
    • Header.Payload.Signature

Header

  • Header에는 Token의 type과 알고리즘(SHA256이나 RSA)으로 구성
    • Base64Url 방식으로 인코딩되어 있다.

Payload

  • 개체(유저 등)의 상태나 부가 정보가 포함된 여러개의 claim으로 구성

  • registered, public, privated claim이 존재한다.

    Registered claims

    • (iss)issuer, (exp)expiration time, (sub)subject, (aud)audience 등 유용한 정보 제공

    • claim의 이름은 3글자

      Public claims

    • 마음대로 정의 가능하나 충돌 방지하기 위해서는 IANA JSON 웹 토큰 레지스트리에 정의하거나 충돌 방지를 포함하는 URI 정의

      Private claims

    • 정보 공유를 위해 생성된 사용자 지정 claim

Signature

  • 인코딩된 Header, 인코딩된 payload, 키(secret), 알고리즘을 가져와서 서명한 부분
  • 메세지가 도중에 변경되지 않았는지 확인하는데 사용

  • JWT Token : Header, Payload, Signature을 모두 합침.

Django에서 JWT 사용


  1. DjangoRestFramework-jwt 설치

     pip install djangorestframework-jwt
  1. Settings.py에 다음 내용 추가

     REST_FRAMEWORK = {
         'DEFAULT_PERMISSION_CLASSES': (
             'rest_framework.permissions.IsAuthenticated',
         ),
         'DEFAULT_AUTHENTICATION_CLASSES': (
             'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
             'rest_framework.authentication.SessionAuthentication',
             'rest_framework.authentication.BasicAuthentication',
         ),
     }
  1. urls.py에 다음 내용 추가

    • url명은 자유로이 변경 가능

    • obtain_jwt_token ⇒ jwt token 획득

      • POST 메서드, data로 username, password 주면 token 획득
    • refresh_jwt_token ⇒ jwt token 갱신

      • POST 메서드, data로 기존 token 주면 새로운 토큰을 response
    • verify_jwt_token ⇒ jwt token 검증

      • POST 메서드, data로 token 주어야 함.
      path('apitokenauth/', obtain_jwt_token),
      path('apitokenrefresh/', refresh_jwt_token),
      path('apitokenverify/', verify_jwt_token),
  1. Token 생성 / 사용 테스트

    • 간단한 api를 만들어 주는데, authentication을 JSONWebTokenAuthentication으로 해주어야 JWT를 사용하여 인증이 진행된다.

      path('api/', APITest.as_view())
      
      class APITest(APIView):
        authentication = [JSONWebTokenAuthentication]
      
        def get(self, request, format=None):
            return Response({'message': 'success call api'})
    • JavaScript로 테스트

      • cors 문제가 발생하여 API 호출이 잘 안되는 문제점이 있었음.

      • django-cors-headers 라이브러리 추가

          pip install django-cors-headers
      • 현재는 API 접근 제한을 따로 걸 필요가 없으므로 전체 허용(CORS_ALLOW_ALL_ORIGINS)

        # INSTALLED_APPS에 추가
        INSTALLED_APPS = [
          ...,
          "corsheaders",
          ...,
        ]
        
        # Settings.py의 맨 아래에 추가
        CORS_ALLOW_ALL_ORIGINS=True
        
        # MIDDLEWARE에 추가, 적어도 CommonMiddleware보다는 위에 가도록
        MIDDLEWARE = [
          ...,
          "corsheaders.middleware.CorsMiddleware",
          "django.middleware.common.CommonMiddleware",
          ...,
        ]
      • 자세한 점은 https://github.com/adamchainz/django-cors-headers

        let userdata = {
          username : 'admin',
          password : 1234,
        };
        
        async function get_JWT_token() {
          try {
              const response = await fetch('http://127.0.0.1:8000/apitokenauth/', {
                  method: "POST",
                  headers: {
                      "Content-Type": "application/json"
                  },
                  body: JSON.stringify(userdata)
              });
              const data = await response.json();
              const token = data["token"];
              console.log(token);
              return token;
          } catch (error) {
              console.log('error');
          }
        };
        
        async function call_api() {
          let api_token = await get_JWT_token();
          const token = api_token;
          const called_api = await fetch('http://127.0.0.1:8000/test/api/', {
                  method: "GET",
                  headers: {
                      "Content-Type": "application/json",
                      "Authorization": "JWT " + token
                  }
              });
          const api_result = await called_api.json();
          return api_result;
        };
      • 오랜만에 async / await 써보니까 많이 헷갈림..

      • 소스를 전체적으로 설명하자면 username이 'admin', password가 1234인 유저의 JWT Token을 얻은 다음, 토큰을 가지고 API를 호출하는 소스이다.

      • API 호출 시에는 headers에 Authorization을 추가해주어야 한다. 값은 JWT + " " + 토큰

      • 유저 데이터가 서버에 없는 경우 JWT 토큰이 발급되지 않으며 당연히 API 호출 시에도 unauthorized가 나타난다.

      • 크롬 개발자 도구에서 console.log가 잘 출력되지 않는다면 필터에 뭐가 입력되어 있는지, 아니면 정보 부분이 체크가 잘 되어있는지 확인해야 한다.

      • 토큰을 로컬 저장소에 저장하거나, 쿠키에 저장할 수 있다는데.. JS를 통해 로컬 저장소에 있는 토큰을 가져올 수 있어서 XSS 공격에 취약하고, 쿠키같은 경우는 secure, httpOnly 속성을 활용하여 막을 수 있다고 한다. 쿠키에 저장하는 방법이 그나마 나아보이긴 하지만, CSRF 문제가 있을 수 있다고 한다.

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] CSRFToken  (0) 2021.10.16
[ Django ] JWT(djangorestframework-simplejwt)  (0) 2021.10.15
[ Django ] Choice  (0) 2021.09.15
[ Django ] MySQL 연동  (0) 2021.09.14
[ Django ] 게시판에 Summernote 에디터 적용  (0) 2021.09.07

Choice


  • 모델의 속성에 원하는 값들중 하나의 값을 넣고싶은 경우 속성에 Choice를 추가해주면 된다.
  • Choice의 타입은 (실제 저장될 값, 사용자에게 표시할 값) 형식으로 들어간다.
  • 사용자에게 표시할 값은 추후 템플릿에서 사용된다.

모델에 Choice 설정


  • 게시판 모델에 Choice 설정 (자유게시판, 파이썬 게시판, 자바 게시판중 하나)
CHOICES = (
        (0, '자유'),
        (1, '파이썬'),
        (2, '자바'),
    )

posttype = models.IntegerField(default=0, choices=CHOICES)

폼에 모델 속성 추가


class QuestionForm(forms.ModelForm):
    class Meta:
        model = Question
        fields = ['posttype', 'subject', 'content', 'image']
        labels = {
            'posttype': '게시판',
            'subject': '제목',
            'content': '내용',
            'image': '이미지',
        }

템플릿에 게시판 타입 Select 추가


<div class="form-group">
    <label for="posttype">게시판</label>
    <select class="form-select" name="posttype" id="id_posttype">
        <!-- choice에서 (실제값, 유저에게 보여질 내용) 지정해 주었으므로, -->
        {% for v, k in form.fields.posttype.choices %}
            <option value="{{ v }}" {% if form.fields.posttype.value == v %} selected {% endif %}>{{ k }}</option>
        {% endfor %}
    </select>
</div>
  • form.fields.posttype.choices
    • 가져오면 위에서 지정한 (실제값, 유저에게 보여질 내용) 리스트가 넘어옴
    • select의 option을 설정할 때 사용
  • select의 name과 id 속성을 맞추어서 잘 설정해 준다.
    • Bootstrap을 사용하였기 때문에 위와 같은 과정이 필요함.
    • 그냥 쓰려면 {{ form.posttype }} 써주면 된다.

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] JWT(djangorestframework-simplejwt)  (0) 2021.10.15
[ Django ] JWT  (0) 2021.10.14
[ Django ] MySQL 연동  (0) 2021.09.14
[ Django ] 게시판에 Summernote 에디터 적용  (0) 2021.09.07
[Django] Rest API 및 Ajax  (0) 2021.07.25

연동 전 필요 라이브러리 설치

mysqlclient 설치


pip install mysqlclient

에러 발생할 경우 자가해결 방법(python3)


sudo apt-get install python3-dev default-libmysqlclient-dev build-essential

Settings.py의 DataBase 수정


  • 우선 기본적으로 설정되어있는 데이터베이스를 수정해 주어야 한다.
  • 찾아보니 OPTIONS에 굳이 파일을 주지 않고 바로 NAME, USER, PASSWORD, HOST, PORT를 줘버려도 되지만, 파일이 훨씬 깔끔해 보여서 파일로 따로 지정

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'OPTIONS':  {
            'read_default_file': os.path.join(BASE_DIR, 'djangoproj.cnf'),
        }
    }
}


djangoproj.cnf


  • db명, db ID, db PW, 기본 문자열셋 지정
  • 호스트, 포트도 지정해주어야 함.. ⇒ 안해주면 에러가 나요..
[client]
database = djangoproject
user = root
password = root
default-character-set = utf8
host: 127.0.0.1
port: 3306


Database 생성


  • 위에서 database = 에 적어준 이름을 가진 데이터베이스를 mysql에서 만들어 두어야 한다.
create database djangoproject character set utf8;

마이그레이션


python manage.py makemigrations
python manage.py migrate
  • 마이그레이션까지 적용되었다면 mysql 연동이 끝남!

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] JWT  (0) 2021.10.14
[ Django ] Choice  (0) 2021.09.15
[ Django ] 게시판에 Summernote 에디터 적용  (0) 2021.09.07
[Django] Rest API 및 Ajax  (0) 2021.07.25
[Django] Django 설치  (0) 2021.07.16

게시판에 어떠한 기능을 추가해볼까 고민하던 중, 글을 쓸 때 글의 작성부분이 밋밋한 점이 마음에 들지 않았다. 직접 구현하기에는 너무 어려울것 같아 구글링을 해보니, Summernote라는 에디터를 사용하면 된다고 하더라. 사용법을 찾아보니 쉬운것 같아 공유해보고자 한다.

출처 : https://summernote.org/getting-started/#include-jscss

1. HTML 헤더


  • Bootstrap으로 구현된 에디터이다 보니, HTML 헤더가 필요하다.
    <!DOCTYPE html>
    <html lang="en">
    ...
    </html>

2. 필요한 파일 추가


<!-- include libraries(jQuery, bootstrap) -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<!-- include summernote css/js -->
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>    

3. 에디터 불러오기


  • 에디터를 적용할 textarea 만들기
    <textarea class="form-control" name="content" id="content" rows="10">{{ form.content.value|default_if_none:'' }}</textarea>
  • 해당 textarea에 summernote 적용
    <script type="text/javascript"> 
      $(document).ready(function() { $("#content").summernote(); }) 
    </script>

4. Django에서 불러오는 부분 처리


  • Django에서 HTML 텍스트를 그대로 불러올 수 없음.
  • 템플릿 필터중에 safe 필터를 사용
    • 보안상에 문제가 있을수도 있으니 신중히 사용해야 함.
    • 악성 스크립트 삽입 공격에 대한 고려가 필요함.
      • 다행히도 Summernote 에디터에서는 입력한 데이터에 대해서는 이스케이프가 적용되서 HTML 태그를 생성하므로 safe 필터를 사용해도 문제가 없을 것이라고 생각된다.
    • 이스케이프가 적용되지 않음, 기본적으로는 이스케이프 적용 => HTML 태그를 적용.
<div class="card-text" style="white-space: pre-line;">
  {{ question.content|safe}}
</div>

이스케이프 적용 / 미적용 차이점


  • 이스케이프가 적용되지 않음
    <b>
  • 이스케이프가 적용됨
    &lt;b&gt;

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] Choice  (0) 2021.09.15
[ Django ] MySQL 연동  (0) 2021.09.14
[Django] Rest API 및 Ajax  (0) 2021.07.25
[Django] Django 설치  (0) 2021.07.16
[Django] pyenv  (0) 2021.07.16

1. 추가 설치

pip install djangorestframework

2. serializer 생성

from rest_framework import serializers
from .models import InterestCompany

class InterestCompanySerializer(serializers.ModelSerializer):
    class Meta:
        model = InterestCompany
        fields = "__all__" # Tuple 형식으로 나열해주어도 된다.

3. ViewSet 생성

  • CRUD를 1개의 View로 구현
    • [GET] api/{pk}/ : detail
    • [PUT] api/{pk}/ : 수정
    • [DELETE] api/{pk}/ : 삭제
    • [GET] api/ : 전체 리스트
    • [POST] api/ : 추가
  • permission_classes 등록이나 생성 시 save 처리 필요(perform_create)
from .serializer import InterestCompanySerializer
from rest_framework import viewsets

class InterestCompanyViewSet(viewsets.ModelViewSet):
    queryset = InterestCompany.objects.all()
    serializer_class = InterestCompanySerializer

4. URL 설정

  • 앱의 urls.py에 다음과 같이 작성
IC_list = InterestCompanyViewSet.as_view({
    'post': 'create',
    'get': 'list'
})

IC_detail = InterestCompanyViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

path('interest/api/', IC_list, name="api-company-list"),
path('interest/api/<int:pk>/', IC_detail, name="api-company-detail"),

⇒ 보았을 때.. 해당 url로 접근하였을 때, post/get/put/patch/delete 등 접근 방식에 따라 취하는 행동 정의하는 거 같음.

5. 테스트

  • TemplateDoesNotExist(rest_framework/api.html) 에러 등장
    • 구글링 결과 .. INSTALLED_APPS에 등록을 안함.

image

  • Settings.py → INSTALLED_APPS → rest_framework 등록
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework'
    'Interest'
]

Ajax 설정


  • jquery load
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
  • Ajax Script 작성
<!--버튼-->
<a class="btn btn-success" id="success" onclick="clickevent(this);" name="{{forloop.counter0}}">관심 기업 등록</a>
<!-- 자기 자신 전달하기 위해선 this로 넘겨주면 된다. -->

function clickevent(self) {
        var idx = $(self).attr('name')
        var name = $('#name'+idx).attr('name')
        var title = $('#title'+idx).attr('name')
        console.log(idx+"//"+name+"//"+title);
        $.ajax({
            type: "POST",
            url: "{% url 'api-company-list' %}",
            data: {
                "company_name" : name,
                "intern_title" : title,
                "duration" : "1900-01-01T12:00"
            },
            dataType: "json",
            success: function(response) {
                window.location.reload()
            },
            error: function(request, status, error) {
                console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+error);

            }
        });
    }
  • Django CSRF 에러시 해결법

    • 인증을 아직 도입하지 않았을 때, 필요 없는경우

      from rest_framework.authentication import SessionAuthentication, BasicAuthentication
      
      class CsrfExemptSessionAuthentication(SessionAuthentication):
        def enforce_csrf(self, request):
            return  # To not perform the csrf check previously happening
      
      #ModelViewSet 맨 윗줄에 추가
      authentication_classes = (CsrfExemptSessionAuthentication, BasicAuthentication)
    • https://stackoverflow.com/questions/30871033/django-rest-framework-remove-csrf

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] MySQL 연동  (0) 2021.09.14
[ Django ] 게시판에 Summernote 에디터 적용  (0) 2021.09.07
[Django] Django 설치  (0) 2021.07.16
[Django] pyenv  (0) 2021.07.16
[Django] 환경 설정  (0) 2021.07.16

1. Django 설치

pip install django==2.2

2. django 버전 확인

django-admin --version

3. 설치되어 있는 파이썬 패키지 목록 보기

pip list

 

'프레임워크 > Django' 카테고리의 다른 글

[ Django ] MySQL 연동  (0) 2021.09.14
[ Django ] 게시판에 Summernote 에디터 적용  (0) 2021.09.07
[Django] Rest API 및 Ajax  (0) 2021.07.25
[Django] pyenv  (0) 2021.07.16
[Django] 환경 설정  (0) 2021.07.16

+ Recent posts