django11
django11

Reputation: 811

How to pass request to django form?

How to pass request to django form?

I am creating a django update profile form where user could change profile email. I want to check if email in form belongs to logged user if not then I want to check if this email is used by others users before setting it as new users email.

Here is my code and this self.request.user.email doesn't work:

def clean_email(self):
        email = self.cleaned_data.get("email")
        owns_email = (email != self.request.user.email)
        if User.objects.filter(email__icontains=email).exists() and owns_email:
            raise forms.ValidationError("This email aldready registered.")
        return email

So maybe there is better solution to solve my problem?

Upvotes: 2

Views: 3558

Answers (2)

Fred
Fred

Reputation: 583

Since you are using a cbv, you can use the get_form_kwargs function from the FormMixin.

It could look something like this:

class UserProfileUpdateView(UpdateView):
...
    def get_form_kwargs(self):
    '''This goes in the Update view'''
        kwargs = super(UserProfileUpdateView, self).get_form_kwargs() #put your view name in the super
        user = self.request.user

        if user:
            kwargs['user'] = user

        return kwargs

Then your form class would look something like this, based on your above code:

class UserProfileUpdateForm:
...
    def __init__(self, *args, **kwargs):
        if kwargs.get('user'):
            self.user = kwargs.pop('user', None)
        super(UserProfileUpdateForm, self).__init__(*args,**kwargs)

    def clean_email(self):
        email = self.cleaned_data.get("email")
        owns_email = (email != self.user.email)
        if User.objects.filter(email__icontains=email).exists() and owns_email:
            raise forms.ValidationError("This email already registered.")
        return email

Upvotes: 6

flowfree
flowfree

Reputation: 16462

The form doesn't have the Request object. You need to manually pass the currently logged in user in the constructor. Your form should look something like this:

class UserProfileForm(forms.Form):
    user = None

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

    ...
    def clean_email(self):
        email = self.cleaned_data['email']
        owns_email = (email != self.user.email)
        if User.objects.filter(email__icontains=email).exists() and owns_email:
            raise forms.ValidationError('This email already registered.')
        return email
    ...

Instantiating the form in the view:

def edit_profile(request):
    form = UserProfileForm(user=request.user)
    ...

Upvotes: 4

Related Questions