André Fratelli
André Fratelli

Reputation: 6068

Mapping a different field OneToOneField in a ModelForm

I have two django models related with a OneToOneField. I'll show the relevant fields:

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True, db_index=True)

And

class PasswordRecovery(models.Model):
    user = models.OneToOneField(User, primary_key=True)
    token = models.CharField(default=utils.make_token)
    password = models.CharField(max_length=128)

Then I have a form for the PasswordRecovery model

class PasswordRecoveryForm(forms.ModelForm):
    password_check = forms.CharField(max_length=128)
    class Meta:
        model = PasswordRecovery
        fields = ('user', 'password', 'password_check')

A few details are omitted here. Tell me if you think they are relevant.

The problem is that the user field shows as a 'select' element and I would like it to be an email field. Instead of being able to chose a user from a lista I want it instead to required the email to be typed.

How can I do this?

Thanks in advance

Upvotes: 1

Views: 1279

Answers (1)

Mounir
Mounir

Reputation: 11736

You should override the clean_user method to pass the User objects

class PasswordRecoveryForm(forms.ModelForm):

    user = forms.EmailField(required=True)
    password_check = forms.CharField(max_length=128)

    class Meta:
        model = PasswordRecovery
        fields = ('user', 'password', 'password_check')

    def clean_user(self):
        user_email = self.cleaned_data['user']
        if User.objects.get(email__iexact=user_email):
            return User.objects.get(email__iexact=user_email)
        return None

    #If you wanna to fill in the email add this
    def __init__(self, *args, **kwargs):
        super(PasswordRecoveryForm, self).__init__(*args, **kwargs)
        if self.instance:
            self.fields['user'].initial = self.instance.user.email

Upvotes: 1

Related Questions