Hello,
I’m relatively new to Django. I’ve been working through Django for Professionals by William Vincent and using the Django docs. I’m trying to create a custom user class and use the Django admin site page to add a custom user.
When I go to the admin site and try to add a new user I get the traceback below.
I thought it may be this, but it doesn’t seem to help:
Any suggestions on where to look next greatly appreciated.
Full traceback:
FieldError at /admin/accounts/customuser/add/
Unknown field(s) (usable_password) specified for CustomUser. Check fields/fieldsets/exclude attributes of class CustomUserAdmin.
Request Method: GET
Request URL: http://localhost:8000/admin/accounts/customuser/add/
Django Version: 5.1.3
Exception Type: FieldError
Exception Value:
Unknown field(s) (usable_password) specified for CustomUser. Check fields/fieldsets/exclude attributes of class CustomUserAdmin.
Exception Location: C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py, line 841, in get_form
Raised during: django.contrib.auth.admin.add_view
Python Executable: C:\Working\GitHub\GiftGenius\.venv\Scripts\python.exe
Python Version: 3.12.7
Python Path:
['C:\\Working\\GitHub\\GiftGenius',
'C:\\Program Files\\Python312\\python312.zip',
'C:\\Program Files\\Python312\\DLLs',
'C:\\Program Files\\Python312\\Lib',
'C:\\Program Files\\Python312',
'C:\\Working\\GitHub\\GiftGenius\\.venv',
'C:\\Working\\GitHub\\GiftGenius\\.venv\\Lib\\site-packages']
Server time: Tue, 19 Nov 2024 00:36:14 -0500
Environment:
Request Method: GET
Request URL: http://localhost:8000/admin/accounts/customuser/add/
Django Version: 5.1.3
Python Version: 3.12.7
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
'crispy_tailwind',
'accounts.apps.AccountsConfig',
'main',
'giftcards',
'shop.apps.ShopConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 839, in get_form
return modelform_factory(self.model, **defaults)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\forms\models.py", line 654, in modelform_factory
return type(form)(class_name, (form,), form_class_attrs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\forms\models.py", line 334, in __new__
raise FieldError(message)
^^^^^^^^^^^^^^^^^^^^^^^^^
During handling of the above exception (Unknown field(s) (usable_password) specified for CustomUser), another exception occurred:
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 718, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\views\decorators\cache.py", line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\sites.py", line 241, in inner
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\views\decorators\debug.py", line 143, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\auth\admin.py", line 121, in add_view
return self._add_view(request, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\auth\admin.py", line 149, in _add_view
return super().add_view(request, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 1961, in add_view
return self.changeform_view(request, None, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 48, in _wrapper
return bound_method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\utils\decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 1820, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 1855, in _changeform_view
ModelForm = self.get_form(
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\auth\admin.py", line 98, in get_form
return super().get_form(request, obj, **defaults)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Working\GitHub\GiftGenius\.venv\Lib\site-packages\django\contrib\admin\options.py", line 841, in get_form
raise FieldError(
^
Exception Type: FieldError at /admin/accounts/customuser/add/
Exception Value: Unknown field(s) (usable_password) specified for CustomUser. Check fields/fieldsets/exclude attributes of class CustomUserAdmin.
From my accounts app:
admin.py:
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.contrib.auth.admin import UserAdmin
from .forms import CustomUserCreationForm, CustomUserChangeForm
from .models import Address
CustomUser = get_user_model()
class AddressAdmin(admin.ModelAdmin):
model = Address
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = [
'email',
'username',
'is_superuser'
]
# fieldsets = UserAdmin.fieldsets + ((None, {'fields': ['role', 'shippingaddress']}),)
# add_fieldsets = UserAdmin.add_fieldsets + ((None, {'fields': ['role', 'shippingaddress']}),)
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.register(Address, AddressAdmin)
forms.py:
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = get_user_model()
fields = (
'email',
'username'
)
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = get_user_model()
fields = (
'email',
'username'
)
models.py:
from django.contrib.auth.models import AbstractUser
from django.db import models
class Address(models.Model):
# id = models.AutoField(primary_key=True)
userid = models.OneToOneField(
'CustomUser', on_delete=models.CASCADE, default='', blank=True, primary_key=True
)
streetaddress1 = models.CharField(max_length=100)
streetaddress2 = models.CharField(max_length=100, blank=True)
city = models.CharField(max_length=100)
state = models.CharField(max_length=50)
zip = models.CharField(max_length=10)
class AddressType(models.IntegerChoices):
RESIDENTIAL = 1
COMMERCIAL = 2
MAILING = 3
SHIPPING = 4
addresstype = models.IntegerField(choices=AddressType, default=1)
def __str__(self):
return (
self.streetaddress1[:30]
if len(self.streetaddress1) <= 30
else f'{self.streetaddress1[:27]}...'
)
class CustomUser(AbstractUser):
'''
Contains:
* username = models.CharField(...)
* password = ...
* first_name = models.CharField(...)
* last_name = models.CharField(...)
* email = models.EmailField(...)
* is_active = models.BooleanField(...)
* is_staff = models.BooleanField(...)
* is_superuser = models.BooleanField(...)
* date_joined = models.DateTimeField(...)
* last_login = models.DateTimeField(...)
'''
'''
address = models.OneToOneField(
Address, on_delete=models.CASCADE, default='', blank=True
)
'''
class UserType(models.IntegerChoices):
ADMIN = 1
CUSTOMER = 2
RECIPIENT = 3
role = models.IntegerField(choices=UserType, default=2)
shippingaddress = models.OneToOneField(
Address,
on_delete=models.CASCADE,
related_name='shippingaddress',
default='',
blank=True,
null=True
)
views.py:
from django.urls import reverse_lazy
from django.views import generic
from .forms import CustomUserCreationForm
class RegisterPageView(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'registration/register.html'