Como o título pergunta, por que os caras do Django decidiram implementar o objeto request.POST com um querydict (que, é claro, por sua vez, torna tudo imutável?)
Eu sei que você pode modificá- lo fazendo uma cópia dos dados da postagem
post = request.POST.copy()
mas por que fazer isso? Certamente seria mais simples permitir que a coisa fosse mutável de qualquer maneira? Ou está sendo usado por algum outro motivo que pode causar problemas?
request.POST
foi enviado com mais dados do que realmente foi.Respostas:
É um pouco misterioso, não é? Várias teorias superficialmente plausíveis revelaram-se erradas na investigação:
Para que o
POST
objeto não precise implementar métodos de mutação? Não: oPOST
objeto pertence àdjango.http.QueryDict
classe , que implementa um conjunto completo de métodos de mutação, incluindo__setitem__
,__delitem__
,pop
eclear
. Ele implementa a imutabilidade verificando um sinalizador quando você chama um dos métodos de mutação. E quando você liga para ocopy
método, você obtém outraQueryDict
instância com o sinalizador mutável ativado.Para melhoria de desempenho? Não: o
QueryDict
classe não ganha nenhum benefício de desempenho quando o sinalizador mutável é desativado.Para que o
POST
objeto possa ser usado como chave de dicionário? Não: osQueryDict
objetos não são hashable.Para que os
POST
dados possam ser construídos preguiçosamente (sem se comprometer a ler toda a resposta), como afirmado aqui ? Não vejo evidência disso no código: pelo que posso dizer, toda a resposta é sempre lida, diretamente ou por meioMultiPartParser
demultipart
respostas.Para protegê-lo contra erros de programação? Já vi isso ser reivindicado, mas nunca vi uma boa explicação sobre o que são esses erros e como a imutabilidade o protege contra eles.
Em qualquer caso,
POST
é não sempre imutável : quando a resposta émultipart
, em seguida,POST
é mutável. Isso parece acabar com a maioria das teorias que você possa imaginar. (A menos que esse comportamento seja um descuido.)Em resumo, não consigo ver nenhuma justificativa clara no Django para o
POST
objeto ser imutável para não-multipart
requisições.fonte
Se a solicitação foi o resultado de um
form
envio do Django , então é razoável para o POSTimmutable
garantir a integridade dos dados entre o envio do formulário e a validação do formulário . No entanto, se a solicitação não foi enviada por meio de umform
envio do Django , o POST émutable
pois não há validação do formulário.Você sempre pode fazer algo assim: (de acordo com o comentário de @leo-the-manic )
fonte
Atualização :
Gareth Rees estava certo ao dizer que os pontos 1 e 3 não eram válidos neste caso. Embora eu ache que os pontos 2 e 4 ainda sejam válidos, deixarei as teses aqui.
(Percebi que o
request.POST
objeto de ambos Pyramid (Pylon) e Django é alguma forma deMultiDict
. Portanto, talvez seja uma prática mais comum do que tornarrequest.POST
imutável.)Não posso falar pelos caras do Django, embora me pareça que poderia por alguns destes motivos:
Performance . objetos imutáveis são "mais rápidos" do que os mutáveis, pois permitem otimizações substanciais. Um objeto é imutável significa que podemos alocar espaço para ele no momento da criação e os requisitos de espaço não estão mudando. Ele também tem coisas como eficiência de cópia e eficiência de comparação por causa disso.Edit : este não é o caso deQueryDict
como Gareth Rees apontou.request.POST
, parece que nenhuma atividade no lado do servidor deve precisar alterar os dados da solicitação . E, portanto, os objetos imutáveis são mais adequados, sem mencionar que têm uma vantagem substancial de desempenho.Objetos imutáveis podem ser usados comoEdit : meu erro, imutável não implica diretamente em hash ; objetos hashable , entretanto, são tipicamente imutáveis também.dict
chaves, o que eu suponho que podem ser muito úteis em algum lugar do Django ..request.POST
(especialmente para plug-ins de terceiros e outros), você pode esperar que esse objeto de solicitação do usuário permaneça inalterado.De alguma forma, essas razões também são respostas genéricas para "imutável versus mutável?" questão. Estou certo de que há muito mais considerações de design do que acima no caso do Django.
fonte
sessions
uma maneira curta de obter e modificar dados entre estados.POST
é umQueryDict
objeto , e esses objetos não obtêm nenhum benefício de desempenho por serem imutáveis. E seu ponto (3) não pode ser a resposta, porque osQueryDict
objetos não têm hash e, portanto, não podem ser usados como chaves de dicionário.QueryDict
antes de responder.requests.POST._mutable = True; requests.POST['foo'] = 'bar'; request.POST._mutable = False
Eu gosto de ser imutável por padrão. Como apontado, você pode torná-lo mutável se precisar, mas deve ser explícito sobre isso. É como 'Eu sei que posso tornar a depuração de meu formulário um pesadelo, mas sei o que estou fazendo agora.'
fonte
Eu encontrei isso em um comentário na Stack Answer https://stackoverflow.com/a/2339963
fonte
Observação: as
multipart
solicitações são imutáveis desde Django 1.11 https://github.com/django/django/blob/stable/1.11.x/django/http/multipartparser.py#L292Eles eram mutáveis nas versões anteriores.
fonte