Как видно из названия, почему ребята из Django решили реализовать объект request.POST с помощью querydict (что, конечно, в свою очередь, делает все это неизменным?)
Я знаю, что вы можете изменить это, сделав копию данных публикации
post = request.POST.copy()
но зачем это делать? Конечно, было бы проще просто разрешить этому объекту быть изменяемым? Или он используется по какой-то другой причине, которая может вызвать проблемы?
request.POST
было отправлено больше данных, чем было на самом деле.Ответы:
Это немного загадка, правда? Несколько внешне правдоподобных теорий в ходе расследования оказываются неверными:
Чтобы
POST
объекту не пришлось реализовывать методы мутации? Нет:POST
объект принадлежит кdjango.http.QueryDict
классу , который реализует полный набор методов мутации , включая__setitem__
,__delitem__
,pop
иclear
. Он реализует неизменяемость, проверяя флаг при вызове одного из методов мутации. И когда вы вызываетеcopy
метод, вы получаете еще одинQueryDict
экземпляр с включенным изменяемым флагом.Для повышения производительности? Нет:
QueryDict
класс не получает выигрыша в производительности, когда изменяемый флаг отключен.Чтобы
POST
объект можно было использовать как ключ словаря? Нет:QueryDict
объекты не хешируются.Чтобы
POST
данные можно было собирать лениво (без необходимости читать весь ответ), как здесь заявлено ? Я не вижу свидетельств этого в коде: насколько я могу судить, всегда читается весь ответ, либо напрямую , либо черезMultiPartParser
дляmultipart
ответов.Чтобы защитить вас от ошибок программирования? Я видел, как это утверждается, но я никогда не видел хорошего объяснения того, что это за ошибки, и как неизменность защищает вас от них.
В любом случае,
POST
это не всегда неизменны : когда ответmultipart
, тоPOST
изменчиво. Похоже, это ставит под сомнение большинство теорий, которые вы можете придумать. (Если это поведение не является недосмотром.)Таким образом, я не вижу в Django четкого обоснования
POST
неизменности объекта для не-multipart
запросов.источник
Если запрос был результатом Джанго
form
представления, то разумно для POST бытьimmutable
для обеспечения целостности данных между формой представлением и формой проверкой . Однако, если запрос не был отправлен через отправку Djangoform
, то POST -mutable
это отсутствие проверки формы.Вы всегда можете сделать что-то вроде этого: (согласно комментарию @ leo-the-manic )
источник
Обновление :
Гарет Рис был прав в том, что пункты 1 и 3 в данном случае недействительны. Хотя я думаю, что пункты 2 и 4 все еще в силе, поэтому я оставлю здесь тезисы.
(Я заметил, что
request.POST
объект как Pyramid (Pylon), так и Django является некоторой формойMultiDict
. Так что, возможно, это более распространенная практика, чем созданиеrequest.POST
неизменяемого.)Я не могу говорить за ребят из Django, хотя мне кажется, что это могло произойти по некоторым из следующих причин:
Исполнение . неизменяемые объекты «быстрее», чем изменяемые, в том смысле, что они допускают существенную оптимизацию. Неизменяемость объекта означает, что мы можем выделить для него пространство во время создания , и требования к пространству не меняются. Он также имеет такие вещи, как эффективность копирования и эффективность сравнения.Изменить : это не так,QueryDict
как указал Гарет Рис.request.POST
, кажется, что никакие действия на стороне сервера не должны изменять данные запроса . И, следовательно, неизменяемые объекты больше подходят, не говоря уже о том, что они имеют существенное преимущество в производительности.Неизменяемые объекты могут использоваться какРедактировать : моя ошибка, неизменяемость не подразумевает напрямую хеширование ; Однако хешируемые объекты обычно также неизменяемы .dict
ключи, что, как я полагаю, может быть очень полезно где-нибудь в Django ..request.POST
(особенно к сторонним плагинам и выходят), вы можете ожидать, что этот объект запроса от пользователя останется неизменным.В каком-то смысле эти причины также являются общими ответами на вопрос «неизменный vs изменчивый?» вопрос. Я уверен, что в случае с Django существует гораздо больше соображений по поводу дизайна, чем указано выше.
источник
sessions
кратковременный способ получения и изменения данных между состояниями.POST
этоQueryDict
объект , и эти объекты не получают преимущества в производительности от неизменности. И ваша точка (3) не может быть ответом, потому чтоQueryDict
объекты не хешируемы и поэтому не могут использоваться в качестве ключей словаря.QueryDict
прежде чем ответить.requests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
Мне нравится, что по умолчанию он неизменен. Как уже указывалось, вы можете сделать его изменяемым, если вам нужно, но вы должны четко указать на это. Это похоже на «Я знаю, что могу превратить отладку моей формы в кошмар, но я знаю, что делаю сейчас».
источник
Я нашел это в комментарии к ответу на стек https://stackoverflow.com/a/2339963
источник
Обратите внимание:
multipart
запросы неизменны с Django 1.11 https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292В предыдущих версиях они были изменяемыми.
источник