tags:

views:

236

answers:

2

Is it possible to get request.user data in a form class? I want to clean an email address to make sure that it's unique, but if it's the current users email address then it should pass.

This is what I currently have which works great for creating new users, but if I want to edit a user I run into the problem of their email not validating, because it comes up as being taken already. If I could check that it's their email using request.user.email then I would be able to solve my problem, but I'm not sure how to do that.

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
A: 

Not that I'm aware of. One way to handle this is have your Form class's __init__ take an optional email parameter, which it can store as an attribute. If supplied at form creation time, it can use that during validation for the comparison you're interested in.

ars
+3  A: 

As ars and Diarmuid have pointed out, you can pass request.user into your form, and use it in valiidating the email. Diarmuid's code, however, is wrong. The code should actually read:

from django import forms

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

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

    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

Then, in your view, you can use it like so:

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

Note that you should pass request.POST as a keyword argument, since your constructor expects 'user' as the first positional argument.

elo80ka
Code example is better in this answer than in mine, so I deleted mine and upvoted this one, although you'll want a == instead of = in the if clause in the clean_email_address method.
Prairiedogg
Fixed. Thanks for catching it :)
elo80ka