get request data in Django form
Solution 1:
As ars and Diarmuid have pointed out, you can pass request.user
into your form, and use it in validating 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, *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
Then, in your view, you can use it like so:
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
Note that you should pass request.POST as a keyword argument, since your constructor expects 'user' as the first positional argument.
Doing it this way, you need to pass user
as a keyword argument. You can either pass request.POST
as a positional argument, or a keyword argument (via data=request.POST
).
Solution 2:
Here's the way to get the user in your form when using generic views:
In the view, pass the request.user
to the form using 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
In the form you will receive the user
with the __init__
function:
class SampleForm(Form):
def __init__(self, user, *args, **kwargs):
super(SampleForm, self).__init__(*args, **kwargs)
self.user = user
Solution 3:
Just so you know, with Django 1.4 and generic class based CreateView and UpdateView, a self.instance is populated on each model form, which allows you to compare the POSTed email vs the current user email.
Here is a code sample, using 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