4 | | In some sections of django.contrib.auth.forms.py, when referring to the User model, Django wisely uses get_user_model(), so whether we decide to use the built-in User model, extend it, or use our own, we always get the right user when importing these forms. |
| 4 | In some sections of `django.contrib.auth.forms.py`, when referring to the User model, Django wisely uses `get_user_model()`, so whether we decide to use the built-in User model, extend it, or use our own, we always get the right user when importing these forms. |
10 | | This is an easy fix and would require all forms in django.contrib.auth.forms to refer to get_user_model() as opposed to the imported built-in User. In the case where a custom User model is not being utilized, get_user_model() will automatically refer to the built-in User. |
| 10 | This is an easy fix and would require all forms in `django.contrib.auth.forms` to refer to `get_user_model()` as opposed to the imported built-in `User`. In the case where a custom User model is not being utilized, `get_user_model()` will automatically refer to the built-in User. |
| 11 | |
| 12 | To reproduce: |
| 13 | |
| 14 | 1. Start a new Django project and initiate an app. |
| 15 | 2. In `models.py` of your app, sub-class `AbstractUser` by importing it from `django.contrib.auth.models`. |
| 16 | 3. In settings.py, add `AUTH_USER_MODEL=yourapp.YourSubClassedUser` (this is all standard). |
| 17 | |
| 18 | {{{ |
| 19 | from django.contrib.auth.models import AbstractUser |
| 20 | |
| 21 | class User(AbstractUser): |
| 22 | pass |
| 23 | }}} |
| 24 | |
| 25 | 4. Register a view and associated url to render a `UserCreationForm`, perhaps using `CreateView` or `FormView`. |
| 26 | |
| 27 | {{{ |
| 28 | from django.shortcuts import render |
| 29 | from .models import User |
| 30 | from django.contrib.auth.forms import UserCreationForm |
| 31 | from django.views.generic.edit import FormView, CreateView |
| 32 | |
| 33 | class RegisterView(CreateView): |
| 34 | model = User |
| 35 | form_class = UserCreationForm |
| 36 | template_name = 'users/register.html |
| 37 | }}} |
| 38 | |
| 39 | 5. Render the form in a template, and run migrations for the first time. |
| 40 | 6. Attempt to start the server. This will throw the following error: |
| 41 | |
| 42 | {{{ |
| 43 | AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User' |
| 44 | }}} |
| 45 | |
| 46 | In the documentation, Django claims that sub-classing the built-in User is not only recommended, but that it will behave exactly like the built-in User model. Patching `django.contrib.auth.forms.py` would ensure this. |