__str__ returned non-string (type NoneType)

Hi there, in a new project I have created a custom user model

class CustomUser(AbstractUser):
    pass

Also the forms:

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(UserCreationForm):
    class Meta:
        model = get_user_model()
        fields = ("email", "username",)

and finally, in the admin:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserCreationForm, CustomUserChangeForm

from .models import CustomUser


class CustomUserAdmin(UserAdmin):
    add_form = CustomUserCreationForm
    form = CustomUserChangeForm
    model = CustomUser
    list_display = ["email", "username",]

admin.site.register(CustomUser, CustomUserAdmin)

I’m getting the following error when I try to add a new user in the admin site:

__str__ returned non-string (type NoneType)

Thanks in advance for your help.

Your CustomUser class inherits from AbstractUser, that inherits from another class AbstractBaseUser that defines a __str__ method that returns the value for the username field by default.
You’re probably adding a user without the username or changing one that does not have one.

I suggest you to implement this method __str__ into your CustomUser class to return a value that’s always a string and check if this stops the error.

1 Like

hello, thanks for your answer. Well, I tried this:

type or paste code here

class CustomUser(AbstractUser):

def __str__(self):
    return self.username

but it still doesn’t work.

After that I made a change in the admin file:

admin.site.register(CustomUser, UserAdmin)

in others words, I commented out the CustomUserAdmin class and register the CustomUser model directly. Then it worked. May be the problem is in the CustomUserAdmin class? If that is true, I could’nt say why and I would like to know it

Right, so when you did this, it indeed overrided the method, but the implementation was the same:

To confirm that this (self.username) is returning a null value, please paste this code and try again.

def __str__(self):
    print("The value of username is", str(self.username))
    return "Bacon"

Then you should see this output on the console:

The value of username is None

If so, this means that you have some bad data into your database. If you can connect into your database and select the user table, then it should display a row with username being null

PS: The “Bacon” return statement is just to make sure that a string is returned. Since you’re adding/editing on the admin you should see “Bacon” somewhere on the feedback message that get’s displayed on the screen after you add or edit a register.

OK I’ll try and come back…

Ok, it worked. so what next?

Have you managed to update this bad data row?

Sorry, I forgot it:

I don’t see any thing bad here

Right, so it looks like this is a issue related to the custom form that you’re using on the admin.

You’re going to need to dig a bit about this. For reference, here’s the code i’ve used to implement a similar behavior. The diff is that i’m not using the username field on my CustomUser class, that it’s called just User. The only difference that i spot is that i put my custom User model directly into the Meta class.

from django.contrib.auth import forms

from .models import User


class UserCreationForm(forms.UserCreationForm):
    class Meta:
        model = User
        fields = ("email", "full_name")


class UserChangeForm(forms.UserChangeForm):
    class Meta:
        model = User
        fields = ("email", "full_name")

Ok, I’ll try but I want you to see this interesting thing I just found. I have another model that have a one to one relationship with the custom user model. When I try to add a new record the combo box in the form shows the value “Bacon” Twice! here is the screenshoot:

Untitled

I refreshed the table in pg admin and still shows the actual usernames, not a “Bacon” value

That’s because the select is getting the values from __str__ method.
You should adjust to something else.
Like:
self.email

1 Like

I think that this behavior is becuase of str() method

I made the chages you indicated:

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

from accounts.models import CustomUser


class CustomUserCreationForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ("username","email", )

class CustomUserChangeForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ("username", "email", )

And it throw the error again:

:

str returned non-string (type NoneType)

I you want can check the repo:
https://github.com/HappyCoder77/hospital_management_app

Can you also share the complete traceback? This will help as well

Hello this is Gulshan Negi
Well, to fix this issue, you should update the str() method in your CustomUser model to return a string representation of the user object. For example, you could modify the method like this:

class CustomUser(AbstractUser):
def str(self):
return self.username

I hope it will help.
Thanks

@Gulshan212 - This was suggested earlier in this thread - __str__ returned non-string (type NoneType) - #3 by HappyCoder77

Side note: When posting code here, enclose the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.

Internal Server Error: /admin/accounts/customuser/23/change/
Traceback (most recent call last):
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\contrib\admin\options.py", line 688, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\utils\decorators.py", line 134, in _wrapper_view
    response = view_func(request, *args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\views\decorators\cache.py", line 62, in _wrapper_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\contrib\admin\sites.py", line 242, in inner
    return view(request, *args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\contrib\admin\options.py", line 1889, in change_view
    return self.changeform_view(request, object_id, form_url, extra_context)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\utils\decorators.py", line 46, in _wrapper
    return bound_method(*args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\utils\decorators.py", line 134, in _wrapper_view
    response = view_func(request, *args, **kwargs)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\contrib\admin\options.py", line 1747, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
  File "C:\Users\goyo\Documents\django\my_hospital\.venv_my_hospital\lib\site-packages\django\contrib\admin\options.py", line 1855, in _changeform_view
    "subtitle": str(obj) if obj else None,
TypeError: __str__ returned non-string (type NoneType)
[03/May/2023 09:03:04] "POST /admin/accounts/customuser/23/change/ HTTP/1.1" 500 117634

The moment of raising the error is this: when I add the user in the first form everything seems to be ok:

Untitled

then, when I add a few data in the change form and save the changes the error raises:

Ok, thanks a lot for your kind suggestions.