Exclude username or password from UserChangeForm in Django Auth
Asked Answered
A

3

12

I'm trying to figure out a way on how to exclude the username and/or password from the UserChangeForm. I tried both exclude and fields but I doesn't work for these two fields.

Here's some code:

class ArtistForm(ModelForm):
    class Meta:
        model = Artist
        exclude = ('user',)

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

    def __init__(self, *args, **kwargs):
        self.helper = FormHelper
        self.helper.form_tag = False
        super(UserForm, self).__init__(*args, **kwargs)
        artist_kwargs = kwargs.copy()
        if kwargs.has_key('instance'):
            self.artist = kwargs['instance'].artist
            artist_kwargs['instance'] = self.artist
        self.artist_form = ArtistForm(*args, **artist_kwargs)
        self.fields.update(self.artist_form.fields)
        self.initial.update(self.artist_form.initial)

    def clean(self):
        cleaned_data = super(UserForm, self).clean()
        self.errors.update(self.artist_form.errors)
        return cleaned_data

    def save(self, commit=True):
        self.artist_form.save(commit)
        return super(UserForm, self).save(commit)
Asturias answered 2/5, 2013 at 11:49 Comment(0)
E
23

For Django v2 just set password to None.

class UserForm(UserChangeForm):
    password = None

    class Meta:
        model = User
        fields = (
            'first_name',
            'last_name',
            'email',
            )
Enclave answered 16/11, 2018 at 11:22 Comment(4)
It's working. But why i explicitly need to tell password = None ? As i don't include password in the fields.Humiliation
That's because UserChangeForm does include password field, so you need to override it.Jessalyn
Saved my day. Very useful hint.Parang
This was very helpful! I would upvote this twice if I could. Btw this still works in version 4.0.3Bosomed
G
11

You won't be able to do this if you use UserChangeForm.

See this https://github.com/django/django/blob/master/django/contrib/auth/forms.py.

You will notice that UserChangeForm on this page explicitly defines username and password. These fields are present in variable declared_fields on the form.

exclude and fields only work on fields which are taken from model defined in Meta. If you explicitly define some field i.e declared_fields, they will be present on the form even if they have been excluded using exclude. So, these fields show for you.

To read more on this check __new__ of ModelFormMetaclass at https://github.com/django/django/blob/master/django/forms/models.py

Workaround:

Do not use UserChangeForm and read its code. It doesn't provide you much. You can write your own form which only extends from ModelForm and set Meta Model as user. Copy the parts from UserChangeForm in your form.

class UserForm(forms.ModelForm):

    class Meta:
        model = User

    def __init__(self, *args, **kwargs):
        #copy any functionality you want form UserChangeForm

    def clean_password(self):
        #copy functionality provided by UserChangeForm 
Gershwin answered 2/5, 2013 at 13:19 Comment(1)
Ok that did the job, but now username and password get NULLed every time I call on save(). Plus the argument from my extended user class don't get saved ether.Asturias
C
1

i think it may help you ...

while iterating over form field in template,write

if for field in UserChangeFormObject:
    {% ifnotequal field.lable password %}
        #process your form field here
    {% endifnotequal%}

Read more here https://docs.djangoproject.com/en/1.6/releases/1.2/

Creole answered 28/3, 2014 at 14:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.