Estou tentando request.user para um método limpo de formulário, mas como posso acessar o objeto de solicitação? Posso modificar o método de limpeza para permitir a entrada de variáveis?
99
A resposta de Ber - armazená-lo em locais de discussão - é uma ideia muito ruim. Não há absolutamente nenhuma razão para fazer dessa maneira.
Uma maneira muito melhor é sobrescrever o __init__
método do formulário para obter um argumento de palavra-chave extra request
,. Isso armazena a solicitação no formulário , onde é necessária e de onde você pode acessá-la em seu método de limpeza.
class MyForm(forms.Form):
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(MyForm, self).__init__(*args, **kwargs)
def clean(self):
... access the request object via self.request ...
e na sua opinião:
myform = MyForm(request.POST, request=request)
ATUALIZADO em 25/10/2011 : Agora estou usando isso com uma classe criada dinamicamente em vez do método, já que o Django 1.3 exibe algumas estranhezas de outra forma.
Em seguida, substitua da
MyCustomForm.__init__
seguinte forma:Você pode acessar o objeto de solicitação de qualquer método de
ModelForm
comself.request
.fonte
__new__
kwargs de que mais tarde será passada para o__init__
método da classe . Nomeando a classeModelFormWithRequest
, acho muito mais claro em seu significado do queModelFormMetaClass
.Por que vale a pena, se você estiver usando visualizações baseadas em classe , em vez de visualizações baseadas em função, substitua
get_form_kwargs
em sua visualização de edição. Código de exemplo para um personalizado CreateView :O código de exibição acima será
request
disponibilizado como um dos argumentos de palavra-chave para a__init__
função de construtor do formulário . Portanto, em seuModelForm
fazer:fonte
request
objetoget_form_kwargs
automaticamente.self.get_object
? OCreateView
estende oSingleObjectMixin
. Mas se isso funciona ou gera uma exceção depende se você está criando um novo objeto ou atualizando um existente; ou seja, teste ambos os casos (e exclusão, é claro).A abordagem usual é armazenar o objeto de solicitação em uma referência de thread local usando um middleware. Em seguida, você pode acessar isso de qualquer lugar em seu aplicativo, incluindo o método Form.clean ().
Mudar a assinatura do método Form.clean () significa que você possui sua própria versão modificada do Django, que pode não ser o que você deseja.
Obrigado, a contagem de middleware parece algo assim:
Registre este middleware conforme descrito na documentação do Django
fonte
**kwargs
, o que significa que você terá que passar o objeto de solicitação comoMyForm(request.POST, request=request)
.Para Django admin, em Django 1.8
fonte
Corri para este problema específico ao personalizar o administrador. Eu queria que um determinado campo fosse validado com base nas credenciais do administrador específico.
Como não queria modificar a visualização para passar a solicitação como um argumento para o formulário, fiz o seguinte:
fonte
obj=obj
não estáobj=None
na linha 11.'function' object has no attribute 'base_fields'
. No entanto, a resposta mais simples (sem encerramento) @ François funciona sem problemas.Você nem sempre pode usar este método (e provavelmente é uma prática ruim), mas se você estiver usando o formulário em apenas uma visão, você pode escopo dentro do próprio método de visão.
fonte
get_form_class
método CBV , se sei que preciso fazer muitas coisas com a solicitação. Pode haver alguma sobrecarga na criação repetida da classe, mas isso apenas a move do tempo de importação para o tempo de execução.A resposta de Daniel Roseman ainda é a melhor. No entanto, eu usaria o primeiro argumento posicional para a solicitação em vez do argumento de palavra-chave por alguns motivos:
Por último, eu usaria um nome mais exclusivo para evitar a substituição de uma variável existente. Assim, Minha resposta modificada se parece com:
fonte
queijo fresco de cheesebaker @ pypi: django-requestprovider
fonte
Eu tenho outra resposta a esta pergunta de acordo com sua exigência de que você deseja acessar o usuário no método limpo do formulário. Você pode tentar isso. View.py
forms.py
Agora você pode acessar o self.instance em qualquer método limpo em form.py
fonte
Quando você deseja acessá-lo por meio de visualizações de classe "preparadas" do Django, como se
CreateView
houvesse um pequeno truque para saber (= a solução oficial não funciona fora da caixa). Por conta própria,CreateView
você terá que adicionar um código como este:= resumidamente, esta é a solução para passar
request
para o seu formulário com as visualizações Criar / Atualizar do Django.fonte