0

I have the following environment in Django 1.5.1:

forms.py

class UserForm(forms.ModelForm):
    class Meta:
        model = User
        widgets = {
            'username': forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'Email Address'}),
            'first_name': forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'First Name'}),
            'last_name': forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'Last Name'}),
            'mobile_phone': forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'Mobile Phone'}),
            'office_phone': forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'Office Phone'}),
        }

    GROUP_CHOICES = [(-1, '[Select]')]
    GROUP_CHOICES += [(group.id, group.name.capitalize()) for group in Group.objects.all()]

    username = forms.EmailField(
        label='Email Address',
        required=True,
        validators=[validate_email],
        widget=forms.TextInput(attrs={'class': 'input-xlarge', 'placeholder': 'Email Address'})
    )
    password1 = forms.CharField(
        label='Password',
        widget=forms.PasswordInput(attrs={'class': 'input-xlarge', 'placeholder': 'Password'})
    )
    password2 = forms.CharField(
        label='Password confirmation',
        widget=forms.PasswordInput(attrs={'class': 'input-xlarge', 'placeholder': 'Password confirmation'})
    )
    group = forms.ChoiceField(
        label='Group',
        choices=GROUP_CHOICES
    )

    def clean_password2(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError('Passwords don\'t match')
        return password2

    def clean_group(self):
        if self.cleaned_data['group'] == '-1':
            raise forms.ValidationError('This field is required.')
        return self.cleaned_data['group']

    def clean_first_name(self):
        if self.cleaned_data['first_name'] == '':
            raise forms.ValidationError('This field is required.')
        return self.cleaned_data['first_name']

    def clean_last_name(self):
        if self.cleaned_data['last_name'] == '':
            raise forms.ValidationError('This field is required.')
        return self.cleaned_data['last_name']

    def save(self, commit=True):
        user = super(UserForm, self).save(commit=False)
        user.set_password(self.cleaned_data['password1'])
        user.username = self.cleaned_data['username']
        if commit:
            user.save()
            user.groups.clear()
            user.groups.add(self.cleaned_data['group'])
            user.save()
        return user

models.py

class User(auth.models.User):
    mobile_phone = models.CharField(
        verbose_name='Mobile Phone',
        max_length=50
    )
    office_phone = models.CharField(
        verbose_name='Office Phone',
        max_length=50
    )

I ALTER the *auth_user* to allow me insert usernames greater than 30 characters long so I would be able to use email as username (I already tried with OneToOneField and with custom model and those approach caused me more work than the expected so I'm not going to take that way)

My questions:

  1. I had to add first_name and last_name cleaners since auth.models.User doesn't have them as required and the widget object don't allow me to set a required attribute, is this the best approach?
  2. I'm having just one problem, the username field still has a MaxValueValidator setting 30 at most. How could I vanish it without overriding it in the form. Since I'm using Class Based Views, overriding the fields won't initiate the username field with model data when I try to update the form via UpdateView class, leaving it empty. The remaining fields don't have any problem

Thanks and sorry if my english looks ugly!

chachan
  • 2,382
  • 1
  • 26
  • 41
  • As for point 1 [altering fields](http://stackoverflow.com/questions/7682804/django-model-forms-setting-a-required-field#answer-7683392) can be done on class initialization – Hedde van der Heide Apr 20 '13 at 14:09

1 Answers1

0

Ok, I found how to avoid this behavior, since MaxValueValidator was running on models side I overrode clean_username in forms.py and add self._meta.exclude += ('username',) to avoid being validated in models. Of course, if you don't have any exclude property in your Meta class then just use self._meta.exclude = ('username',)

chachan
  • 2,382
  • 1
  • 26
  • 41