2009-07-29 20 views
40

È possibile ottenere i dati request.user in una classe di modulo? Voglio pulire un indirizzo e-mail per assicurarmi che sia univoco, ma se è l'indirizzo e-mail degli utenti attuali dovrebbe passare.ottenere i dati di richiesta nel modulo Django

Questo è quello che attualmente ho che funziona alla grande per la creazione di nuovi utenti, ma se voglio modificare un utente mi imbatto nel problema della loro e-mail non convalidare, perché si presenta già come preso. Se potessi verificare che è la loro email usando request.user.email, allora sarei in grado di risolvere il mio problema, ma non sono sicuro di come farlo.

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 

risposta

56

Come hanno sottolineato ars e Diarmuid, puoi passare request.user nel modulo e utilizzarlo per convalidare l'email. Il codice di Diarmuid, tuttavia, è sbagliato. Il codice dovrebbe in realtà leggere:

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 

Quindi, secondo lei, è possibile utilizzarlo in questo modo:

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 

noti che si dovrebbe passare request.POST come un argomento parola chiave, dal momento che il costruttore si aspetta 'utente' come il primo argomento posizionale.

In questo modo, è necessario passare user come argomento di parola chiave. È possibile passare request.POST come argomento posizionale o argomento parola chiave (tramite data=request.POST).

+3

L'esempio di codice è migliore in questa risposta che nel mio, quindi ho eliminato il mio e lo ha svalutato, anche se vorrete un == anziché = nella clausola if nel metodo clean_email_address. – Prairiedogg

+0

corretto. Grazie per averlo preso :) – elo80ka

+2

> Si noti che è necessario passare request.POST come argomento della parola chiave, poiché il costruttore si aspetta 'utente' come primo argomento posizionale. questo è specificamente il motivo per cui non si dovrebbero mescolare gli argomenti parola chiave (cioè, facoltativo) con ** kwargs. Invece, la funzione di costruzione non dovrebbe avere utente e deve semplicemente metterla come prima riga: utente = kwargs.pop ('utente') se 'utente' in kwargs Altro – jorelli

0

Non che io sappia. Un modo per gestirli è che l'__init__ della classe Form accetta un parametro email opzionale, che può memorizzare come attributo. Se fornito al momento della creazione del modulo, può utilizzarlo durante la convalida per il confronto a cui sei interessato.

3

Proprio per questo motivo, con Django 1.4 e CreateView e UpdateView basati su classi generiche, su ogni modulo del modello viene compilato un self.instance, che consente di confrontare l'e-mail POSTed con l'e-mail dell'utente corrente.

Ecco un esempio di codice, utilizzando 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

Ecco il modo per ottenere l'utente nel modulo quando si utilizza una vista generici:

Nella vista, passare il request.user al modulo utilizzando 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 

Nella forma si riceverà il user con la funzione __init__:

+2

Questo è meglio http://stackoverflow.com/a/6062628/758202 – zzart

+0

In realtà preferisco in questo modo, ma dovresti rimuovere l'utente da kwargs prima di chiamare il costruttore .. qualcosa come "self.user = kwargs.pop ('utente') ' – intelis

Problemi correlati