Question

I'm trying to make an edit account page for my django site. I'm trying to use my register form with slight modifications as the info is basically all the same. The issue I'm running into is when the user clicks update, django checks for unique usernames even and returns an error with the following if they left their username is the same. If they don't change it, it should check that field value equals the logged in username and skip it.

"User with this Username already exists"

So far I've overridden the clean method, passed through request.user to the form, and check if the logged in username is the same as the field username. Looking through other stack overflow questions it seems people just del self._errors['username'] but I get a key error with that. self._errors isn't even instantiated. I've also tried setting the "Unique" property to false but it still gives me the error. I'm lost so any help would be appreciated.

My Forms Class:

class updateAccount(forms.ModelForm):
        username = forms.CharField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Username'}))
        email = forms.EmailField(required=True, widget=forms.TextInput(attrs={'placeholder': 'Email Address'}))
        first_name = forms.CharField(max_length=100, required=True, widget=forms.TextInput(attrs={'placeholder': 'First Name'}))
        last_name = forms.CharField(max_length=100, required=True, widget=forms.TextInput(attrs={'placeholder': 'Last Name'}))      

        class Meta:
            model = User
            fields = ('username','email','first_name','last_name')
            exclude = ('password',)

        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop("request")
            super(updateAccount, self).__init__(*args, **kwargs)

        def clean(self):
            if self.request.user.username == self.cleaned_data.get('username'):
                self.fields['username'].required = False

            super(updateAccount, self).clean()

            return self.cleaned_data

        def save(self, commit=True):
            user = super(updateAccount, self).save(commit=False)
            if commit:
                user.save()
            return user
Was it helpful?

Solution

Use built-in UserChangeForm instead.

forms.py

from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import User

class MyUserChangeForm(UserChangeForm):
    def __init__(self, *args, **kwargs):
        super(MyUserChangeForm, self).__init__(*args, **kwargs)
        del self.fields['password']

    class Meta:
        model = User
        fields = ('username','email','first_name','last_name')

views.py

def home(request):
    if request.method == 'POST':
        form = MyUserChangeForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
    else:
        form = MyUserChangeForm(instance=request.user)

    return render(request, 'change_user.html', {"form": form})

OTHER TIPS

I had the same error no matter whether I inherit UserChangeForm, AuthenticationForm or a forms.ModelForm. So I simply switched to inherit from forms.Form and bound it's fields to model in views.py and it works such way. A little bit more code however the error disappeared. To me it seems that Django tries to be a little be too smart in this case - forms.ModelForm should not check User model fields for non-existance of users automatically.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top