2009-07-29 24 views
40

Czy można uzyskać dane request.user w klasie formularza? Chcę wyczyścić adres e-mail, aby upewnić się, że jest unikalny, ale jeśli jest to aktualny adres e-mail użytkownika, powinien on przejść.pobierz dane żądania w Django z formularza

To jest to, co aktualnie mam, który działa świetnie do tworzenia nowych użytkowników, ale jeśli chcę edytować użytkownika, napotkam problem z jego e-mailem, który nie jest sprawdzany, ponieważ pojawia się jako już zajęty. Gdybym mógł sprawdzić, czy to jest ich adres e-mail za pomocą request.user.email, to będę w stanie rozwiązać mój problem, ale nie jestem pewien, jak to zrobić.

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 

Odpowiedz

56

Jak zauważyli ars i Diarmuid, możesz przekazać request.user do formularza i użyć go do sprawdzania poprawności wiadomości e-mail. Kod Diarmuid jest jednak błędny. Kod powinien rzeczywiście przeczytać:

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 

Następnie w widoku, można go używać tak:

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 

pamiętać, że należy przekazać jako argument request.POST słów kluczowych, ponieważ konstruktora spodziewa się, że "użytkownik" będzie pierwszym argumentem pozycyjnym.

Robiąc to w ten sposób, musisz podać user jako argument słowa kluczowego. Możesz przekazać request.POST jako argument pozycyjny lub argument słowa kluczowego (przez data=request.POST).

+3

Przykładowy kod jest lepszy w tej odpowiedzi niż w moim, więc usunąłem i przeszedłem tę, chociaż będziesz potrzebował = = zamiast = w klauzuli if w metodzie clean_email_address. – Prairiedogg

+0

Naprawiono. Dzięki za złapanie go :) – elo80ka

+2

> Pamiętaj, że powinieneś przekazać request.POST jako argument słowa kluczowego, ponieważ Twój konstruktor oczekuje "użytkownika" jako pierwszego argumentu pozycyjnego. to jest właśnie dlatego nie należy mieszać argumentów słów kluczowych (to znaczy opcjonalnych) z ** kwargs. Zamiast tego konstruktor nie powinien mieć użytkownika i po prostu umieścić go jako pierwszą linię: użytkownik = kwargs.pop ("użytkownik"), jeśli "użytkownik" w kwargs else Brak – jorelli

0

Nie jestem tego świadomy. Jednym ze sposobów radzenia sobie z tym problemem jest ustawienie w klasie Form __init__ opcjonalnego parametru e-mail, który można zapisać jako atrybut. Jeśli zostanie dostarczony w czasie tworzenia formularza, może go użyć podczas sprawdzania poprawności do porównania, które Cię interesuje.

3

Django 1.4 i generine CreateView i UpdateView tworzą osobne formularze, które pozwalają porównać POSTed email z aktualnym emailem użytkownika.

Oto przykładowy kod, za pomocą wstawek

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

oto sposób, aby użytkownik w formularzu przy użyciu rodzajowe widoki:

W widoku, przekaż request.user do formularza przy użyciu 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 

W formularzu otrzymasz user z funkcją __init__:

class SampleForm(Form): 
    def __init__(self, user, *args, **kwargs): 
     super(SampleForm, self).__init__(*args, **kwargs) 
     self.user = user 
+2

To jest lepsze http://stackoverflow.com/a/6062628/758202 – zzart

+0

faktycznie wolę w ten sposób, ale należy usunąć użytkownika z kwargs przed wywołaniem konstruktora .. coś takiego jak 'self.user = kwargs.pop („user”) ' – intelis