I see your point in the first paragraph. So, maybe it is better to change the default register model according to the current trend on the net. To me it looks more conventional to make it 3-field model: username, email and password (without confirmation). This way it seems to be easier for a Django user to omit one of username/email fields or add the password confirmation field easily.
Anyway, such change might not be much of a concern for someone that knows the internals of Django well and might not be necessary. But I would like to tell you my situation so that Django developers may see it in the eyes of a not so experienced Django user.
I would like to switch to username+email+password(no confirmation) sign-up in my project, and allow the user to choose either email or username at login (which is quite popular today). Due to my research it is kind of easy to switch to email+password but not email-or-username+password login. Even this requires me to inherit and modify User and UserManager classes. Since Django, including the admin section, is completely based on these classes, I am hesitant to touch it as I don’t know how deep the rabbit hole goes, at what parts of the framework do I need to refer to these Custom classes, and what problems and hazards might occur in the most unexpected area.
Also, it is necessary to declare USERNAME_FIELD = ‘email’ in models.py. Since username and email are different things, this gives the impression of hacking, and makes me, as the not-so-experienced Django user, wonder if any problems might occur due to validity checks somewhere in the depths of Django or even Python. Maybe I would feel more safe if it was declared as something like LOGIN_FIELD instead of USERNAME_FIELD.
Another thing that troubles me is that Django is quite large and if I can cover all the parts of the framework to make it compatible with an ‘additional’ USERNAME_FIELD and have all parts operate in harmony. It is good to study the code but this might not be the case for large frameworks like Django as the study would require too much analyzing and one main purpose of the framework is to speed up coding.
Server security is an issue too. I might patch my own solution and think it works but wonder if I can keep up with Django’s validation and security standards on that.
This is how the picture looks to me. Anyway, most probably, I will give it a shot to turn the original username field into an email-or-username field. What comes to my mind is:
- Define email form field as required at sign-up.
- Make the USERNAME_FIELD inside models.py a list, which contains both username and email at the same time.
- Find password validity checking code inside Django and remove password2 comparison. Or just copy-paste the password1’s value inside password2 and hide it from the browser screen.
- When the website user presses submit button, check the content of the original username field with an ‘if statement’. If the website user entered an email inside the username field, POST the form to the alternative template that has email field instead of the username field. If the website user did not enter email, POST it to default template with username field.
This way it is possible to get use of already built in labels, hints, validity checks, error texts and also database queries for email and username fields without modification.
- Need to implement uniqueness check to email. Trace USERNAME_FIELD in models.py, find all references and modify it to support both email and username. This might be the trickiest part.
- After you think you are done hope that the rabbit hole does not go so deep.
The goal is to have a fully functional email-or-username login field. Do you think this approach would work? What are your opinions in terms of efficiency, security and other aspects?