# ModelForm is not saving UserModel

**URL:** <https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093>\
**Category:** Using Django\
**Created:** [November 4, 2020, 8:55pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093 "2020-11-04T20:55:51Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 4, 2020, 8:55pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/1 "2020-11-04T20:55:51Z")

</div>

Hi everyone,

I’m stucked at saving my ModelForm whereas I did save() the form :

models.py :

```auto
class UserModel(AbstractBaseUser):
    username = models.CharField(max_length=20, unique=True)
    email = models.EmailField(max_length=20)
    password1 = models.CharField(max_length=20)
    password2 = models.CharField(max_length=20)

    USERNAME_FIELD = "username"

```

views.py

```auto
def signupUser(request):
    if request.method == "POST":
        form = signupUserForm(request.POST)

        if form.is_valid():
            print("SIGNUP FORM IS VALID")
            form.save()
            return redirect("site_base:home")
        else:
            print("ERROR : ", form.errors)
    else:
        form = signupUserForm()

    template_name = "accounts/signup.html"
    context = {
        "form":form,
    }

    return render(request, template_name, context)

```

forms.py

```auto
class signupUserForm(forms.ModelForm):
    class Meta:
        model = UserModel
        fields = [
            "username",
            "email",
            "password1",
            "password2",
        ]

        widgets = {
            "password1":PasswordInput(),
            "password2":PasswordInput(),
        }

```

Indeed when I try to create a User via my signupUserForm I do obtain a User object but then I get nothing in my user database…

```auto
>>> from accounts.models import UserModel
>>> from accounts.forms import signupUserForm
>>> request_post = {"username":"myuser","email":"myuser@mail.com","password1":"myuser","password2":"myuser"}
>>> form = signupUserForm(request_post)
>>> form.is_valid()
True
>>> form.save()
<UserModel: myuser>

```

But then when I go into the Djagno admin board I cannot see my user stored in the User section.

Why ?

Thank you in advance

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 5, 2020, 1:47am UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/2 "2020-11-05T01:47:10Z")

</div>

Did you make the settings change for [AUTH\_USER\_MODEL](https://docs.djangoproject.com/en/3.1/ref/settings/#auth-user-model)?

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 5, 2020, 8:23am UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/3 "2020-11-05T08:23:49Z")

</div>

Hi @KenWhitesell !

Thank you for your answer.

Well, I did add this to my settings.py :

```auto
from accounts.models import UserModel
AUTH_USER_MODEL = UserModel

```

I then deleted my db in order to reset everything but when I try to migrate I get an error :

```auto
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.   

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 5, 2020, 1:05pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/4 "2020-11-05T13:05:25Z")

</div>

From the docs:

> AUTH\_USER\_MODEL = ‘myapp.MyUser’

Notice that the setting is looking for the name of the class (a string), not the class model itself.

Remove the import and specify the model as a string.

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 5, 2020, 1:13pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/5 "2020-11-05T13:13:31Z")

</div>

You’re right !

I now have a new bug :

```auto
user = UserModel._default_manager.get_by_natural_key(username)     
AttributeError: 'Manager' object has no attribute 'get_by_natural_key'  

```

Looks like I still have to change something else ?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 5, 2020, 1:27pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/6 "2020-11-05T13:27:29Z")

</div>

One of the differences between AbstractUser and AbstractBaseUser is that AbstractUser defines the `objects` attribute on the model, while AbstractBaseUser does not. So if you’re building your model based on AbstractBaseUser, you will need to provide a manager.  
This is covered in the section [Writing a manager for a custom user model](https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#writing-a-manager-for-a-custom-user-model)

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 5, 2020, 4:11pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/7 "2020-11-05T16:11:37Z")

</div>

Thank you @KenWhitesell, I understand it better now.

For the moment being I will stick with AbstractUser.

If I understood it right I know have to also specify a custom authentication backend ?

Because the authentication will fail according to my debug information :

```auto
[05/Nov/2020 17:07:40] "GET /accounts/signup HTTP/1.1" 200 850
SIGNUP FORM IS VALID
[05/Nov/2020 17:07:54] "POST /accounts/signup HTTP/1.1" 302 0
[05/Nov/2020 17:07:54] "GET / HTTP/1.1" 200 340
[05/Nov/2020 17:07:56] "GET /accounts/login HTTP/1.1" 200 630
<QueryDict: {'csrfmiddlewaretoken': ['MY7OCwXaiwQwdglEuCWobY0AlfTCOnLQimKhRR6Er8CkOrjnot0GNnPbbaobRp2D'], 'username': ['myuser'], 'password': ['myuser']}>
LOGIN FORM IS VALID
ERROR : Failed to authenticate user
[05/Nov/2020 17:08:01] "POST /accounts/login HTTP/1.1" 200 645  

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 5, 2020, 4:58pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/8 "2020-11-05T16:58:10Z")

</div>

This _may_ go back to the previous reply you received in your earlier thread where @mblayman points out the need to store passwords encrypted. ([Create User ModelForm and working with it](https://forum.djangoproject.com/t/create-user-modelform-and-working-with-it/5027/2))

In your model above, you’re storing the two password fields as text rather than storing a single encrypted password field. You might want to look at the Django source code for AbstractUser / User to see how it’s being handled by the system.

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 5, 2020, 6:00pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/9 "2020-11-05T18:00:15Z")

</div>

Yes I remember but as I use AbstractUser instead of AbstractBaseUser I shouldn’t have any issues.

Here is the code snippet I found in AbstractBaseUser code :

```auto
    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)
        if self._password is not None:
            password_validation.password_changed(self._password, self)
            self._password = None

    def set_password(self, raw_password):
        self.password = make_password(raw_password)
        self._password = raw_password

```

=\> Does that mean that I have to implement these methods myself ?  
=\> Or maybe is it better in that case to use AbstractBaseUser instead of AbstractUser to benefit from the already written methods ? (Not opting for the premade User model in order to learn more)

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 6, 2020, 12:00am UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/10 "2020-11-06T00:00:10Z")

</div>

Take a look at the standard Django [UserCreationForm](https://github.com/django/django/blob/658bcc16f1b814b3a063d3fa16fabaea8b471863/django/contrib/auth/forms.py#L82) to see how they handle it.

It’s not that you need to implement the `set_password` method, but you will need to call it.

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 7, 2020, 10:29am UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/11 "2020-11-07T10:29:31Z")

</div>

Well that’s interesting, I’ve seen that there is both UserCreationForm and AuthenticationForm in the source code.

I’ve tried to inherit from the two hereafter :

```auto
class signupUserForm(UserCreationForm):
    class Meta:
        model = UserModel
        fields = [
            "username",
            "email",
            "password1",
            "password2",
        ]

        widgets = {
            "password1":PasswordInput(),
            "password2":PasswordInput(),
        }

class loginUserForm(AuthenticationForm):
    username = forms.CharField(label="Username : ")
    password = forms.CharField(label="Password : ", widget=PasswordInput)

```

But I can’t authenticate my user, I get a blank error in my debug output.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 7, 2020, 4:53pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/12 "2020-11-07T16:53:09Z")

</div>

`<conjecture>`  
Notice that in the UserCreationForm, password1 and password2 are designed as form fields, not as model fields. I’m guessing that there’s some sort of conflict between the two definitions such that your model fields named password1 and password2 are not being populated from the form.  
`</conjecture>`

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 7, 2020, 6:14pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/13 "2020-11-07T18:14:44Z")

</div>

So according to you I should rewrite my UserModel in order to match with the UserCreationForm ?

Because when I go to the admin board I now have the users which were created through my signupUserForm.

The issue is when using the loginUserForm which inherits from AuthenticationForm.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 7, 2020, 7:41pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/14 "2020-11-07T19:41:43Z")

</div>

No, I’m not actually saying that. I don’t know what your specific needs, requirements, or objectives are for this exercise. I _am_ suggesting that if you’re going to make these types of changes, that you’re not going to be able to rely upon the built-in forms to work with your modified model.

You’ve defined a model with a password1 and password2 field in the models. Ok, that’s fine, but that’s not how Django does it. Django stores the single (encrypted) password in a field named password (AbstractBaseUser, and so by extension, AbstractUser and User) - it doesn’t store the password1 and password2 fields in the model.

Since you’re inheriting from AbstractBaseUser, that means you’d have all of password, password1 and password2 in the model.

You’re inheriting a Form that was designed for a different model with fields named the same as model fields that you have, creating the possibility of one of them being hidden by the other. (And I don’t know which would be used at any particular point.)

So you mention that the users are being created - but is the password field being populated with the encrypted password? More importantly, is it being encrypted with the password supplied by the form, and not from the (assumed) blank / null field being hidden by the other instance?

---

<div class="post-metadata">

**Author:** ![valenciano8](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/valenciano8/32/1062_2.png) [@valenciano8](https://forum.djangoproject.com/u/valenciano8)\
**Post date:** [November 7, 2020, 9:49pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/15 "2020-11-07T21:49:12Z")

</div>

It is that I was searching things on the Web and found this article : [https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html](https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html)

My goal is to learn more about Django through an exercise where :

- The user can authenticate himself with his/her mail adress.
- The user can have a biography

According to the article above, there is no choice but to use AbstractBaseUser and implement everything myself right ?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [November 7, 2020, 11:21pm UTC](https://forum.djangoproject.com/t/modelform-is-not-saving-usermodel/5093/16 "2020-11-07T23:21:50Z")

</div>

Regarding that article, I’d be a little concerned given its age. July 2016 puts it at Django 1.9. I don’t specifically know what, if anything, has changed in the authentication system since then, but it is a factor I would be looking at closely. (I typically find two common issues with old articles - one is advice that is wrong due to underlying system changes and the other is advice that is suboptimal because of advances within Django since the time that article was written. Again, I have no direct knowledge regarding this specific topic relative to that post, but it’s something you should be aware of.)

So it appears to me that you have identified two different and somewhat divergent goals. Yes, there are times when doing something yourself provides a much better education than just reading someone else’s code - and it’s a practice I’ve done myself.

However, outside that exercise, if I wanted to create a system using email address as the username, I would be looking at [djangopackages.org](http://djangopackages.org) to find one of the [third-party packages](https://github.com/tmm/django-username-email) to keep from having to do the work myself.

Regardless of the specific approach, for something like the biography, I would always implement that as a [“profile model”](https://docs.djangoproject.com/en/3.1/topics/auth/customizing/#extending-the-existing-user-model) associated with the User model by a one-to-one field. (The User model is likely going to be the most frequently accessed model on any system with a high percentage of authenticated users. I want that model to be as lean as possible.)

But you always have choices, and there are always tradeoffs. To say that “there is no choice but to…” isn’t accurate. How much you’ll need to implement yourself will depend upon how close your requirements are to the existing implementation.

For example, someone else on here on this forum posted a thread of messages where they wanted the person to be able to log in using _either_ their username _or_ their email address. They ended up writing a custom authenticator that had the single form field for entry and checked what the user had entered to both the username and email fields to find the User object to use. In that particular place, they didn’t change the user object at all, other than making email address unique.  
Sometimes it pays just to get a bit creative.
