I've read and re-read the other questions regarding this issue and I'm still unable to create a custom Django User model. I keep getting the error: Manager isn't available; 'auth.User' has been swapped for 'Users.User'
.
If not clear by the error, I've created a Users
app in which the models.py
file defines a custom user class User
.
Here's are the relevant files from my project, UserTest
:
UserTest> UserTest> settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'Users'
]
AUTH_USER_MODEL = 'Users.User'
User
model and connecting it to a Profile
model (not strictly relevant to the issue but a fundamental aspect of the approach.)UserTest > Users > models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
email = models.CharField(max_length=128, blank=False, unique=True, verbose_name='Email', name='email')
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
...
User
model in my Users
App's admin.py (not sure if this is required for testing quick front-end functionality?)UserTest > Users > admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
I've created some basic forms and a view to allow front-end submission of relevant user and profile data. Given the error, I didn't feel they were relevant but I can include them if someone feels they are. Again, the error is as follows:
Manager isn't available; 'auth.User' has been swapped for 'Users.User'
I had initially created a custom User
model using the AbstractBaseUser
class, which the documentation describes states a custom Manager class must also be created. I had the same error using that approach and didn't read that the same customization was needed when using this approach, relying on AbstractUser
In my UserTest > Users > forms.py file, I've tried accessing my Users.models.User
model in both of the following ways:
from .models import User
get_user_model()
function as such:from django.contrib.auth import get_user_model
User = get_user_model()
The second approach seems to have solved this issue for many others, such as the question HERE but doesn't help me (unless I'm missing something).
The full traceback of the error is here:
Internal Server Error: /test-form/
Traceback (most recent call last):
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\core\handlers\base.py", line 126, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\core\handlers\base.py", line 124, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\...\Desktop\UserTest\Users\views.py", line 19, in NewUserRegistration
print("USERFORM:", user_form, type(user_form), dir(user_form))
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\utils\html.py", line 397, in <lambda>
klass.__str__ = lambda self: mark_safe(klass_str(self))
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 142, in __str__
return self.as_table()
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 284, in as_table
errors_on_separate_row=False,
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 202, in _html_output
top_errors = self.non_field_errors() # Errors that should be displayed above all fields.
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 313, in non_field_errors
return self.errors.get(NON_FIELD_ERRORS, self.error_class(error_class='nonfield'))
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 180, in errors
self.full_clean()
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\forms.py", line 383, in full_clean
self._post_clean()
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\contrib\auth\forms.py", line 107, in _post_clean
super()._post_clean()
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\forms\models.py", line 403, in _post_clean
self.instance.full_clean(exclude=exclude, validate_unique=False)
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\db\models\base.py", line 1137, in full_clean
self.clean()
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\contrib\auth\models.py", line 338, in clean
self.email = self.__class__.objects.normalize_email(self.email)
File "C:\Users\...\Desktop\UserTest\venv\lib\site-packages\django\db\models\manager.py", line 188, in __get__
cls._meta.swapped,
AttributeError: Manager isn't available; 'auth.User' has been swapped for 'Users.User'
[26/Oct/2018 09:47:02] "POST /test-form/ HTTP/1.1" 500 118088
I appreciate any help. Usually, if I'm able to type an entire post on SO without having an "aha" moment I know I'm pretty screwed.
UPDATE 1: Adding forms.py
and views.py
In my UserTest > Users
app, the views.py
and forms.py
are as follows:
UserTest > Users > forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.core.exceptions import ValidationError
from django.contrib.auth import get_user_model
User = get_user_model()
class NewUser(UserCreationForm):
email = forms.EmailField(max_length=96)
password = forms.PasswordInput()
username = forms.CharField(max_length=18)
def clean_email(self):
email = self.cleaned_data['email'].lower()
r = User.objects.filter(email=email)
if r.count():
raise ValidationError("Email already exists")
return email
def save(self, commit=True):
user = User.objects.create_user(
self.cleaned_data['email'],
self.cleaned_data['password'],
self.cleaned_data['username']
)
return user
NOTE: Here I have tried both the get_user_model()
approach as well as importing my custom User
class from Users.models
and neither resolve the error.
UserTest > Users > views.py
from django.shortcuts import render
from django.contrib import messages
from .forms import NewUser
def NewUserRegistration(request):
if request.method == 'POST':
user_form = NewUser(request.POST)
if user_form.is_valid():
user_form.save()
messages.success(request, 'Account Created Successfully!')
else:
user_form = NewUser()
return render(request, 'Users/test-form.html', {'user_form': user_form})
As the documentation explains, forms such as UserCreationForm" are tied to User and need to be rewritten or extended to work with a custom user model".
So, as shown there, you need to override the inner Meta class to point to your model:
class NewUser(UserCreationForm):
...
class Meta(UserCreationForm.Meta):
model = get_user_model()