django-request.POST 객체가 변경되지 않는 이유는 무엇입니까?


109

제목에서 알 수 있듯이 Django 사람들은 왜 querydict를 사용하여 request.POST 객체를 구현하기로 결정 했습니까?

게시물 데이터를 복사하여 수정할 수 있다는 것을 알고 있습니다.

post = request.POST.copy()

근데 왜 이렇게? 어쨌든 변경 가능하도록 허용하는 것이 더 간단할까요? 아니면 문제를 일으킬 수있는 다른 이유로도 사용되고 있습니까?


1
왜 그것이 변경되기를 원합니까? 데이터를 가져 와서보기에서 사용 / 수정할 수 있습니다. 여기에 데이터를 추가 request.POST하면 실제보다 더 많은 데이터가 제출 된 인상을 만들 수 있습니다 .
Simeon Visser 2012 년

11
나는 그것이 변경 되기를 바라는 것이 아닙니다 . 더 이상 아이스크림이 차가워지기를 바랍니다. 아이스크림의 경우하지만,이 경우 없는 추위가 녹아 다음이 큰 팔자 '난장판을 만들기위한 꾸중 얻을. 하지만 request.POST 객체를 사용하면 ... 내 코드를 망쳐 놓으면 망쳐 놓을 것입니다. 나는 개발자들이 POST 객체에 데이터를 추가하고 문제를 일으키는 고유 한 현상이 있다는 것을 몰랐기 때문에 "수정"을 목표로하는 것이 이상하게 보입니다.
bharal

좋은 질문; 정말 생각하지 못했습니다.
Burhan Khalid

1
내 클라이언트가 때때로 JSON 데이터 (변경 가능) 및 URL 양식 인코딩 (변경 불가능) 메시지를 제출했기 때문에이 문제가 산발적으로 나타났습니다.
owenfi

2
비영어권 사용자의 경우 "mutify"는 단어가 아닙니다. 올바른 구문은 "you can mutate it"또는 "you can modify it"입니다. 개발자를 성별 할 필요도 없습니다. "남자"대신 "Django 팀"또는 "핵심 개발자"를 사용할 수 있습니다.
alexmuller

답변:


131

약간의 미스터리 죠? 표면적으로 그럴듯한 몇 가지 이론이 조사에서 잘못된 것으로 밝혀졌습니다.

  1. 그래서 것을 POST목적은 돌연변이 메소드를 구현하지 않습니다? 아니 다음 POST객체가 속한 django.http.QueryDict클래스 돌연변이 방법의 전체 세트를 포함하여 구현, __setitem__, __delitem__, popclear. 돌연변이 메소드 중 하나를 호출 할 때 플래그를 확인하여 불변성을 구현합니다. copy메서드 를 호출 QueryDict하면 변경 가능한 플래그가 설정된 다른 인스턴스가 생성됩니다.

  2. 성능 향상을 위해? 아니오 : QueryDict변경 가능한 플래그가 꺼져있을 때 클래스는 성능 이점을 얻지 못합니다.

  3. 있도록 POST객체는 사전 키로 사용할 수 있습니까? 아니요 : QueryDict개체는 해시 할 수 없습니다.

  4. 그래서 여기에 주장 된 것처럼POST 데이터를 느리게 (전체 응답을 읽지 않고) 작성할 수 있습니까? 나는 코드에서 이것에 대한 증거를 볼 수 없다. 내가 말할 수있는 한, 전체 응답은 항상 직접 또는 응답 을 위해 읽혀진다 .MultiPartParsermultipart

  5. 프로그래밍 오류로부터 보호하기 위해? 나는 이것이 주장하는 것을 보았지만 이러한 오류가 무엇인지, 그리고 불변성이 어떻게 당신을 보호하는지에 대한 좋은 설명을 본 적이 없습니다.

어떤 경우 POST입니다 항상 불변하지 : 응답이있을 때 multipart, 다음 POST변경할 수 있습니다. 이것은 당신이 생각할 수있는 대부분의 이론에 키보시를 넣는 것 같습니다. (이 행동이 감독이 아니라면.)

요약하면, Django에서 객체가 비 요청에 대해 변경 불가능 하다는 명확한 근거볼 수 없습니다 .POSTmultipart


Django에서 이와 같은 거친 가장자리를 많이 발견했습니다. 하지만 어느 시점에서는 누군가에게 이해가되었을 것입니다.
Dan Passaro 2014 년

2
나는 다른 스택 답변에서 이것을 발견했습니다. "그리고 그것은 느리게 빌드 될 수 있도록 불변이어야합니다. 복사는 모든 POST 데이터를 강제로 가져옵니다. 복사 할 때까지 모두 가져 오지 못할 수도 있습니다. 또한 다중 스레드 WSGI의 경우 서버가 합리적으로 잘 작동합니다. 변경이 불가능하면 도움이됩니다. "
Seaux

12
@Seaux에 댓글을 달고 자 할 때 SO 답변을 느리게 읽으면 안됩니다. ;-)
Chris Wesseling 2014 년

3
나는 당신이 무슨 짓을했는지 볼 @ChrisWesseling
Seaux

2
더 좋은 점은 django 테스트 클라이언트에 요청을 보낼 때 querydict를 변경할 수 있다는 것입니다.
user1158559

82

요청이 Django form제출 의 결과 인 경우 POST가 양식 제출 과 양식 유효성 검사 사이immutable데이터 무결성을 보장하는 것이 합리적입니다 . 그러나 요청이 Django 제출을 통해 전송 되지 않은 경우 POST는 양식 유효성 검사가 없기 때문입니다.formmutable

당신은 항상 다음과 같이 할 수 있습니다 : ( @ leo-the-manic의 코멘트에 따라 )

#  .....
mutable = request.POST._mutable
request.POST._mutable = True
request.POST['some_data'] = 'test data'
request.POST._mutable = mutable
# ......

3
@JoshK : 댓글 작성자가 POST를 변경 가능하게 만들고 싶었고이 답변의 코드 스 니펫이 도움이되었습니다.
ShreevatsaR 2015-06-26

새 키, 값을 추가 할 수 있지만 기존 데이터를 변경할 수 없습니다.
Vamsidhar Muggulla

좋은. 그리고이 코드를 사용하는 사람은 누구나 자신이하는 일을 알고있을 것입니다.
John Pang

@VamsidharMuggulla 추가 및 변경이 모두 가능합니다. 삭제도 허용됩니다.
Antony Hatchkins

5

업데이트 :

Gareth Rees는이 경우 포인트 1과 3이 유효하지 않다는 것이 옳았습니다. 2 번과 4 번이 여전히 유효하다고 생각하지만 여기에 논문을 남겨 두겠습니다.

( request.POSTPyramid (Pylon)과 Django 의 객체가.의 어떤 형태 라는 것을 알아 챘습니다 MultiDict. 그래서 아마도 request.POST불변으로 만드는 것보다 더 일반적인 관행 일 것 입니다.)


나는 Django 사람들을 위해 말할 수는 없지만 다음과 같은 이유 때문에 그렇게 할 수 있다고 생각합니다.

  1. 성능 . 변경 불가능한 객체는 상당한 최적화를 허용한다는 점에서 변경 가능한 객체보다 "빠릅니다". 객체가 불변이라는 것은 생성시 공간을 할당 할 수 있으며 공간 요구 사항이 변경되지 않음을 의미합니다. 그것 때문에 복사 효율성 및 비교 효율성과 같은 것도 있습니다. 편집 : 이것은QueryDictGareth Rees가 지적한경우가 아닙니다.
  2. 의 경우 request.POST서버 측에서 요청 데이터 를 변경해야하는 활동이없는 것 같습니다 . 따라서 불변의 객체는 성능상의 이점이 있다는 것은 말할 것도없고 더 적합합니다.
  3. 불변 객체는 dict키로 사용될 수 있는데, 장고 어딘가에서 매우 유용 할 수 있다고 생각 합니다. 편집 : 내 실수, 불변 은 직접적으로 해시 가능을 의미하지 않습니다 . 그러나 해시 가능한 객체는 일반적으로 변경 불가능 합니다.
  4. 전달할 때 request.POST(특히 타사 플러그인 및 외부로) 사용자의이 요청 객체가 변경되지 않은 상태로 유지 될 것으로 예상 할 수 있습니다.

어떤면에서 이러한 이유는 "불변성 대 가변성?"에 대한 일반적인 대답이기도합니다. 질문. Django의 경우 위의 것보다 훨씬 더 많은 디자인 고려 사항이 있다고 확신합니다.


1
마지막 경우는 정말 중요합니다. 정말 보안에 관한 것입니다. 이것이 Django sessions가 상태간에 데이터를 가져오고 수정하는 단기적인 방법을 제공 하는 이유 입니다.
CppLearner

2
이 경우 귀하의 요점 (1)은 답이 될 수 없습니다. POSTQueryDict객체 입니다. 그리고 이러한 객체들은 불변성으로 인한 성능상의 이점을 얻지 못합니다. 그리고 당신의 요점 (3)은 답이 될 수 없습니다. 왜냐하면 QueryDict객체는 해시 할 수 없기 때문에 사전 키로 사용할 수 없기 때문 입니다.
Gareth Rees

@GarethRees 이것을 지적 해 주셔서 감사합니다. 사실 나는 틀렸다. 나는 이것을 수정하기 위해 내 대답을 업데이트했습니다. 내가 QueryDict답장하기 전에 더 많은주의를 기울 였어야 했다.
KZ

7
보안 점은 논쟁, 예를 들어 보인다 @CppLearnerrequests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
댄 Passaro

4

나는 그것이 기본적으로 불변하는 것을 좋아합니다. 지적했듯이 필요한 경우 변경 가능하게 만들 수 있지만 이에 대해 명시해야합니다. 그것은 마치 '내 양식 디버깅을 악몽으로 만들 수는 있지만 지금 무엇을하고 있는지 알고 있습니다.'와 같습니다.


2

Stack Answer https://stackoverflow.com/a/2339963 에 대한 의견에서 이것을 발견했습니다.

그리고 느리게 만들 수 있도록 불변이어야합니다. 복사는 모든 POST 데이터를 가져옵니다. 사본이 나오기 전까지는 모두 가져 오지 못할 수도 있습니다. 또한 다중 스레드 WSGI 서버가 합리적으로 잘 작동하려면 이것이 변경 불가능한 경우 유용합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.