Django Rest API : ValueError: badly formed hexadecimal UUID string

I'm getting the following error while attempting to create a superuser on Django 5.0.4 Rest API

ValueError: badly formed hexadecimal UUID string

Here is the stack trace :

Here is the stack trace : 

File "/home/ubuntu/my_api/manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/core/management/base.py", line 413, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 89, in execute
    return super().execute(*args, **options)
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/core/management/base.py", line 459, in execute
    output = self.handle(*args, **options)
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 131, in handle
    error_msg = self._validate_username(
  File "/home/ubuntu/myenv/lib/python3.10/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 304, in _validate_username
    self.UserModel._default_manager.db_manager(database).get_by_natural_key(
  File "/home/ubuntu/my_api/my_auth/models.py", line 55, in get_by_natural_key
    uuid = UUID(uuid)
  File "/usr/lib/python3.10/uuid.py", line 177, in __init__
    raise ValueError('badly formed hexadecimal UUID string')
ValueError: badly formed hexadecimal UUID string

Model definitions:

from uuid import UUID

class UserManager(DjangoUserManager):
    def get_by_natural_key(self, uuid):
        if not isinstance(uuid, UUID):
            uuid = UUID(uuid)

        return self.get(uuid=uuid)


class User(AbstractUser):
    """"
    Custom user model to change behaviour of the default user model
    such as validation and required fields.
    """
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True,verbose_name=_("UUID"))

What I've tried

  1. delete migrations
  2. flush database using flush command
  3. reset database using reset_db command

In method get_by_natural_key, the value of the field from USERNAME_FIELD is passed, so in your case you get username instead of uuid, which causes an error.

If you create a superuser via console, get_by_natural_key with username value as argument will be called here.

I think in your case, you probably shouldn't override get_by_natural_key at all. Your uuid field has a default value and will always be created automatically when the instance is created. However, here's a slightly simplified example where it really makes sense:

class CustomUserManger(BaseUserManager):  
    def get_by_natural_key(self, email):  
        email_field = self.model.get_email_field_name()  
        return self.get(**{f'{email_field}__iexact': email})  
  
  
class User(AbstractBaseUser, PermissionsMixin):  
    id = models.UUIDField(  
        primary_key=True,  
        default=uuid.uuid4,  
        editable=False,  
    )  
    email = models.EmailField(unique=True)  
    is_active = models.BooleanField(default=True)  
    is_staff = models.BooleanField(default=False)  
    date_joined = models.DateTimeField(default=timezone.now)  
  
    objects = CustomUserManger()  
  
    EMAIL_FIELD = USERNAME_FIELD = 'email'

Suppose you decided not to use the username field at all, and decided to keep email as a unique identifier. Then we can override USERNAME_FIELD = “email”. And override the get_by_natural_key method to look for email in the database in a case-insensitive way.

Вернуться на верх