반응형

django의 Model attribute들은 아래와 같이 class attribute의 형태를 하고 있다. 

 

models.py

from django.db import models

class Model(models.Model):
    # These are class attributes, but specific to Django models
    attribute1 = models.CharField(max_length=255)
    attribute2 = models.TextField()

    def __str__(self):
        return f"{self.attribute1} - {self.attribute2}"

 

아래처럼 Model의 instance를 초기화할 때, kwargs 형태로 attribute1과 attribute2를 넘긴다.

new_instance = Model(attribute1=attribute1, attribute2=attribute2)
new_instance.save()

 

Model attribute는 class attribute로 정의되어 있는데, 초기화 과정에서 넘겨진 attribute1과 attribute2는 class attribute가 초기화된 것인가? 하는 질문이 순간 생겼다.

 

결론적으로 말하면 그렇지 않다.

 

Model에서 class 내에 직접 정의된 attribute1 및 attribute2와 같은 필드는 class attribute이다.

그러나 이는 해당 Model에 특수(specific)한 class attribute이며, 그 목적은 Model과 관련된 Database 테이블의 구조를 정의하는 것이다.

 

django의 Model class에서, class body 내부와 method 외부에서 직접 정의된 attribute들은 class attribute지만 다른 Python class들의 일반 class attribute들과는 다르다:

  • Model attribute들은 Model의 database table의 필드들을 정의한다.
  • 그러므로 django가 Model의 필들을 database column들에 매핑하기 위해 사용하는 descriptor로 기능한다.

반면에, instance attribute들은 Model을 instance화할 때 생성되며 각 instance마다 고유하다.

Instance 초기화를 위해 넘겨진 attribute1과 attribute2는 instance attribute의 값이며, 해당 특정 instance를 위해 세팅된다.

Instance attribute는 Model의 각 instance마다 다르며, class attribute와도 다르다.

즉 new_instance.attribute1와 new_instance.attribute2는 Model.attribute1와 Model.attribute2에 영향을 주지 않는다.

반응형
반응형

만약 django 사용시 form을 제출했을 때 CSRF 오류를 리턴한다면, CSRF token을 request에 같이 삽입한 뒤에 전송하지 않았기 때문에 발생한 것이다.

그래서 아래와 같은 에러 화면을 보게 될 거다:

 

 

django framework는 CSRF(Cross Site Request Forgery) 공격을 방지하기 위해, 편리하게 token을 사용한다.

쉽게 말해, django에서 리턴된 HTML 파일에는 CSRF token 값이 박혀 있어서, form의 submit에 의해 request가 django 서버로 오면, 앞서 보냈던 CSRF token 값이 request에 잘 포함되어 다시 돌아왔는지 서버에서 검증하는 것이다.

 

이를 적용하려면, django 서버에서 리턴하는 HTML 파일에 CSRF token이 같이 저장되도록 하면 된다.

 

HTML 파일에서, POST 방식을 사용하는 <form> tag 내에 {% csrf_token %}라는 template tag를 추가하면 된다.

해당 <form>이 render될 때, django는 {% csrf_token %}를 실제 CSRF token 값으로 대체한다.

(CSRF token 값은 django 서버에 의해 생성되며, HTML 파일의 매번 리턴 시마다 변경된다.)

 

CSRF token 값은 일반적으로 <form> 내의 hidden된, "csrfmiddlewaretoken" 라는 이름을 가진 <input> tag로서 HTML 페이지에 포함된다. 

<input type="hidden" name="csrfmiddlewaretoken" value="실제 CSRF token 값">

 

해당 token은 form이 submit될 때 browser에 의해 request에 포함되며, django 서버에 의해 그 유효성이 검증된다. 

그 뒤에, django 서버는 request에 대한 view page를 연결해준다.

 

 

[CSRF token 사용법]

 

사용자에게 리턴되어 render될 HTML 코드 내에, {% csrf_token %}를 <form> tag 내부에 박아주자.

<body>
    <form action="http://localhost:8000/memo/writeMemo/" method="POST" id="memoWriteForm">
        {% csrf_token %}
        <input type="text" name="memContent" placeholder="메모">
    </form>
    <div>
        <button type="submit" form="memoWriteForm">메모 쓰기</button>
    </div>
</body>

 

실제 render되는 html 출력 값을 확인해보자.

django에 의해 {% csrf_token %}가 hidden된 <input> tag로 변경되었다. 

<body>
    <form action="http://localhost:8000/memo/writeMemo/" method="POST" id="memoWriteForm">
        <input type="hidden" name="csrfmiddlewaretoken" value="JgcYMzhTo2srNdLGPF7nEFoOkiw1HgOOHenFgoQtlPbFrb7BwKP3dLenSQiPkfib">
        <input type="text" name="memContent" placeholder="메모">
    </form>
    <div>
        <button type="submit" form="memoWriteForm">메모 쓰기</button>
    </div>
</body>

 

 

반응형

+ Recent posts