Hi guys, I'm new here. I customised the User model of my project by inheriting from AbstractBaseUser, I've also made a custom Manager through BaseUserManager and added an auth backend to login through email instead of username. The reason I did this is to let users register and login using their email but still have a username, that doesn't have to be unique (they're differentiated through a discriminator not unlike the one Discord uses, if you know it, like brzrkr#0001 and brzrkr#2342 may exist at the same time and both be known as brzrkr).
The problem is, when I create a user with `manage.py createsuperuser`, the database saves the email in the "username" field and the username in the "email" field, even though I set all overridden variables to the correct fields (see below for code). NOTE: I have also posted a question about this on stackoverflow but it's been ignored for some days now, so I've looked for a place where people may be more familiar with Django in particular. Here is the link to it: https://stackoverflow.com/q/50104202/8599834 Now here's the *code of the User model* not including irrelevant methods: class User(AbstractBaseUser, PermissionsMixin): """Override of the Django class to handle user authentication.""" # ==Identification== # To allow for multiple users with the same username, users are publicly identified with username#identifier. # Internally, only the couple username + identifier must be unique, but either can be duplicate on their own. username = models.CharField(max_length=150, db_column="user_username") # The identifier is stored as a string of digits including trailing zeroes. # It is assigned at creation and modification of a user's nick using the first value that doesn't conflict. identifier = models.CharField(max_length=settings.IDENTIFIER_DIGITS) email = models.EmailField(unique=True, db_column="user_email") objects = UserManagerOverride() # Override the default manager to customise user creation. is_superuser = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=True) USERNAME_FIELD = "email" EMAIL_FIELD = "email" REQUIRED_FIELDS = ["username"] class Meta: unique_together = ("username", "identifier") This is the *Manager*. This is mostly identical to what BaseUserManager does except for some quirks. I haven't included the generate_identifier method because it's not relevant: class UserManagerOverride(BaseUserManager): """Override of the default Django user manager.""" def _create_user(self, email, username, password, **extra_fields): """Override the parent function to create a user and save it in the database.""" if not email: raise ValueError('An email is required.') # Prepare the data to be stored into the database. email = self.normalize_email(email) username = self.model.normalize_username(username) identifier = self.generate_identifier(username) # Make the user instance. user = self.model(username=username, email=email, identifier=identifier, **extra_fields) # Add the password after encrypting. user.set_password(password) try: # Save to database. user.save(using=self._db) except Exception: # If there was an error, scratch the user row to preserve integrity with User and UserData primary keys. user.delete() raise else: # Create a UserData record for this user. # Thanks to the try-else, we only do this if the code raised no exceptions. UserData.objects.create(user=user) return user def create_user(self, email, username, password=None, **extra_fields): """Override parent function to create a regular user account.""" extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(email, username, password, **extra_fields) def create_superuser(self, email, username, password, **extra_fields): """Override parent function to create a superuser account.""" extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) if extra_fields.get('is_staff') is not True: raise ValueError('Superuser must have is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Superuser must have is_superuser=True.') return self._create_user(username, email, password, **extra_fields) And finally the *auth backend*, although this should only come into play when trying to log in, so it isn't involved in the problem (at least for now): class EmailBackend(ModelBackend): """Allow authentication using email instead of username.""" def authenticate(self, username=None, password=None, **kwargs): user_model = get_user_model() try: user = user_model.objects.get(email=username) except user_model.DoesNotExist: return None else: if user.check_password(password): return user return None Please let me know if you need more info and thank you for reading this. I hope someone can walk me out of this conundrum... :P -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/ef29e0ef-9d60-49d3-8a65-5e80aee7691d%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.

