3

I want to create a signup form for a Django custom user model using abstractuser. I don't want anything special, just the ability to later on add custom fields if needed.

I understand from the docs that I need to:

  • set AUTH_USER_MODEL
  • define a custom user model by subclassing AbstractUser
  • define a custom model manager by subclassing UserManager
  • subclass UserCreationForm and UserChangeForm

Here's my current code:

My settings.py:

AUTH_USER_MODEL = 'users.CustomUser'

My models.py:

from django.contrib.auth.models import AbstractUser, UserManager


class CustomUserManager(UserManager):
    pass    

class CustomUser(AbstractUser):
    objects = CustomUserManager()

My forms.py:

from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm

from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta(UserCreationForm.Meta):
        model = CustomUser
        fields = UserCreationForm.Meta.fields

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = UserChangeForm.Meta.fields

My 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 CustomUser


class CustomUserAdmin(UserAdmin):
    model = CustomUser
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm


admin.site.register(CustomUser, CustomUserAdmin)

My views.py:

from django.urls import reverse_lazy
from django.views import generic

from .forms import CustomUserCreationForm

class SignUp(generic.CreateView):
    form_class = CustomUserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'signup.html'

Upon submission of the signup form get the error message:

OperationalError at /users/signup/
no such table: users_customuser

I've nuked my database and done makemigrations and then migrate from scratch. Something is wrong with my form and perhaps admin, too.

wsvincent
  • 207
  • 4
  • 13
  • Did you register in `admin.py`? https://docs.djangoproject.com/en/2.0/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project – schrodingerscatcuriosity Dec 20 '17 at 22:22
  • Yes, forgot to add that code. Now included. – wsvincent Dec 20 '17 at 22:42
  • [This answer](https://stackoverflow.com/a/47240584/2996101) may help you. – raratiru Dec 21 '17 at 15:35
  • Thanks for the link. I think the issue has to do with my forms. I keep thinking (perhaps wrongly) that I just need to subclass existing functionality since I'm using `abstractUser` and not trying to rewrite everything or even add custom fields to my User at this point. – wsvincent Dec 21 '17 at 15:58
  • Yes indeed, your approach is very pythonic. – raratiru Dec 21 '17 at 16:14
  • When did you makemigrations? The [docs](https://docs.djangoproject.com/en/dev/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project) read: "Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migrations or running manage.py migrate for the first time". Could it be the issue? – raratiru Dec 21 '17 at 16:22
  • Ha, thanks. I think the issue is needing to rewrite UserCreationForm from scratch. – wsvincent Dec 21 '17 at 16:22
  • Yes, I've started nuking my database and re-running makemigrations and migrate each time I make changes now. That was causing issues earlier but not now I don't think. – wsvincent Dec 21 '17 at 16:22
  • For those curious, I wrote up a tutorial with the working solution to this problem of using a custom user model with Django. https://wsvincent.com/django-custom-user-model-tutorial/ – wsvincent Nov 20 '18 at 10:36

1 Answers1

4

See the Django docs about rewriting the User model: Referencing the User Model

However, if your user model extends AbstractBaseUser, you’ll need to define a custom ModelAdmin class.

In admin.py, you should get the user model from django.contrib.auth:

admin.py:

from django.contrib.auth import get_user_model

Class MyCustomModelAdmin...

CustomUser = get_user_model()

admin.site.register(CustomUser, MyCustomModelAdmin)

EDIT: I think the issue may be with your use of UserCreationForm.

My forms.py:

from django import forms
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

class Meta:
    model = CustomUser
    fields = [list fields here]
Stolson
  • 100
  • 6
  • I think you've identified the issue but I'm not able to get your solution to work. I've updated the code above to show the revised admin.py but still get the same error: `Manager isn't available; 'auth.User' has been swapped for 'users.CustomUser'. – wsvincent Dec 21 '17 at 15:15
  • EDIT: Sorry I missed that you were just using AbstractUser and not AbstractBaseUser – Stolson Dec 21 '17 at 15:18
  • Since I'm using `AbstractUser` not `AbstractBaseUser` I'm trying to just extend `UserAdmin` per the docs. "If your custom user model extends django.contrib.auth.models.AbstractUser, you can use Django’s existing django.contrib.auth.admin.UserAdmin class." – wsvincent Dec 21 '17 at 15:19
  • Django has a full example you can look at here, I think it might be helpful: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#a-full-example – Stolson Dec 21 '17 at 15:27
  • Thanks. I'll study that further as it does the complete go using `AbstractBaseUser`. Seems like it should not require as much code to use `AbstractUser` but perhaps that's not the case. – wsvincent Dec 21 '17 at 15:31
  • Yes I think the form is the issue. I've added `views.py`. I think the issue is the form but, still stumped. – wsvincent Dec 21 '17 at 15:57
  • I think the issue may be caused by using from django.contrib.auth.forms.UserCreationForm – Stolson Dec 21 '17 at 15:59
  • Yup seems I need to rewrite UserCreationForm from scratch. https://stackoverflow.com/questions/16562529/django-1-5-usercreationform-custom-auth-model#16570743 – wsvincent Dec 21 '17 at 16:21
  • Ok got it to work with the edited code above. Fixed the form, added `CustomUserCreationForm` and `CustomUserChangeForm`. I needed to delete the sqlite database and run migrate again several times for it to work. I'll write this all up in a blog post for others. Still seems like A LOT of work to simply use `abstractuser` for a custom user model. – wsvincent Dec 21 '17 at 17:04