2009-07-29 27 views
40

¿Es posible obtener datos de request.user en una clase de formulario? Quiero limpiar una dirección de correo electrónico para asegurarme de que sea única, pero si se trata de la dirección de correo electrónico actual de los usuarios, entonces debería pasar.obtener datos de solicitud en Django formulario

Esto es lo que tengo actualmente, que funciona muy bien para crear nuevos usuarios, pero si quiero editar a un usuario me encuentro con el problema de que su correo electrónico no valida, porque parece que ya se tomó. Si pudiera verificar que es su correo electrónico utilizando request.user.email, entonces podría resolver mi problema, pero no estoy seguro de cómo hacerlo.

class editUserForm(forms.Form): 
    email_address = forms.EmailField(widget=forms.TextInput(attrs={'class':'required'})) 

    def clean_email_address(self): 
     this_email = self.cleaned_data['email_address'] 
     test = UserProfiles.objects.filter(email = this_email) 
     if len(test)>0: 
      raise ValidationError("A user with that email already exists.") 
     else: 
      return this_email 

Respuesta

56

Como han señalado Ars y Diarmuid, puede pasar request.user en su formulario y usarlo para validar el correo electrónico. El código de Diarmuid, sin embargo, está mal. El código en realidad debería decir:

from django import forms 

class UserForm(forms.Form): 
    email_address = forms.EmailField(widget = forms.TextInput(attrs = {'class':'required'})) 

    def __init__(self, *args, **kwargs): 
     self.user = kwargs.pop('user', None) 
     super(UserForm, self).__init__(*args, **kwargs) 

    def clean_email_address(self): 
     email = self.cleaned_data.get('email_address') 
     if self.user and self.user.email == email: 
      return email 
     if UserProfile.objects.filter(email=email).count(): 
      raise forms.ValidationError(u'That email address already exists.') 
     return email 

Luego, en su opinión, se puede usar como tal:

def someview(request): 
    if request.method == 'POST': 
     form = UserForm(request.POST, user=request.user) 
     if form.is_valid(): 
      # Do something with the data 
      pass 
    else: 
     form = UserForm(user=request.user) 
    # Rest of your view follows 

en cuenta que debe pasar request.POST como un argumento de palabra clave, ya que su constructor espera 'usuario' como el primer argumento posicional.

Haciéndolo de esta manera, debe pasar user como argumento de palabra clave. Puede pasar request.POST como un argumento de posición o un argumento de palabra clave (a través del data=request.POST).

+3

El ejemplo de código es mejor en esta respuesta que en la mía, así que eliminé la mía y la modifiqué, aunque querrá un == en lugar de = en la cláusula if en el método clean_email_address. – Prairiedogg

+0

Reparado. Gracias por atraparlo :) – elo80ka

+2

> Tenga en cuenta que debe pasar request.POST como un argumento de palabra clave, ya que su constructor espera 'usuario' como el primer argumento posicional. esto es específicamente por qué no debe mezclar argumentos de palabras clave (es decir, opcionales) con ** kwargs. En cambio, el constructor no debería tener usuario y simplemente poner esto como la primera línea: usuario = kwargs.pop ('usuario') si 'usuario' en kwargs else Ninguno – jorelli

0

No es que yo sepa. Una forma de manejar esto es hacer que su clase de formulario __init__ tome un parámetro de correo electrónico opcional, que puede almacenar como un atributo. Si se proporciona en el momento de creación del formulario, puede usarlo durante la validación para la comparación que le interese.

3

Para que lo sepan, con Django 1.4 y la clase genérica CreateView y UpdateView, una instancia propia se rellena en cada formulario modelo, que le permite comparar el correo electrónico POST versus el correo electrónico actual del usuario.

Aquí es un ejemplo de código, usando mixin

class EmailUniqueMixin(object): 
    """ 
    Ensure each User's email is unique 
    on the form level 
    """ 
    def clean_email(self): 
     email = self.cleaned_data['email'] 
     existing_email = User.objects.filter(email=email).exclude(pk=self.instance.id) 
     if existing_email: 
      raise forms.ValidationError('That email address already exists') 
     else: 
      return email 
24

aquí está la manera de conseguir que el usuario en su forma al usar las vistas genéricas:

En la vista, pasar el request.user a la forma usando get_form_kwargs :

class SampleView(View): 
    def get_form_kwargs(self): 
     kwargs = super(SampleView, self).get_form_kwargs() 
     kwargs['user'] = self.request.user 
     return kwargs 

En el formulario, recibirá el user con la función __init__:

+2

Esto es mejor http://stackoverflow.com/a/6062628/758202 – zzart

+0

En realidad prefiero esta forma, pero debe eliminar el usuario de kwargs antes de llamar al constructor ... algo así como 'self.user = kwargs.pop ('user') ' – intelis

Cuestiones relacionadas