10đź‘Ť
Rather than modify the User class directly or do subclassing, you can also just repurpose the existing fields.
For one site I used the “first_name” field as the “publicly displayed name” of a user and stuff a slugified version of that into the “username” field (for use in URLs). I wrote a custom auth backend to allow people to log in using their “public name” or their email address, and I enforce the uniqueness of both of those at registration time. This plays nicely with other reusable apps and doesn’t introduce extra tables or queries.
For another site I didn’t want usernames at all, just unique emails. In order to satisfy Django’s need for a unique username, I just hashed the email address and used that as the username (you have to base64-encode the hash to squeeze it under 30 characters). Custom auth backend to allow login with email.
If backwards-compatibility weren’t an issue, there are a lot of improvements I’d love to see made to django.contrib.auth and the User model to make them more flexible. But there’s quite a lot you can do inside the current constraints with a little creativity.
7đź‘Ť
The Django User model is structured very sensibly. You really don’t want to allow arbitrary characters in a username, for instance, and there are ways to achieve email address login, without hacking changes to the base model.
To simply store additional information around a user account, Django supports the notion of user profiles. While you don’t need to rely on the built in support to handle this, it is a convention that is commonly followed and it will allow you to play nice with the reusable Django apps that are floating around in the ether. For more information, see here.
If you want to actually modify the core User model but also “play nice” with reusable apps that rely on it, you’re opening a bit of a Pandora’s Box. Developers make base assumptions about how the core library is structured, so any changes may cause unexpected breakage. Nonetheless, you can monkeypatch changes to the base model, or branch a copy of Django locally. I would discourage the latter, and only recommend the former if you know what you’re doing.
- Difference between Response and HttpResponse django
- Error Using CheckConstraint in Model.Meta along with Django GenericForeignKey – Joined field references are not permitted in this query
- Multiple user type sign up with django-allauth
- Django annotate and count: how to filter the ones to include in count
7đź‘Ť
I misread the question. Hope this post is helpful to anyone else.
#in models.py
from django.db.models.signals import post_save
class UserProfile(models.Model):
user = models.ForeignKey(User)
#other fields here
def __str__(self):
return "%s's profile" % self.user
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'
This will create a userprofile each time a user is saved if it is created.
You can then use
user.get_profile().whatever
Here is some more info from the docs
http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
0đź‘Ť
You face a bit of a dilemma which really has two solutions if you’re committed to avoiding the profile-based customization already pointed out.
- Change the
User
model itself, per Daniel’s suggestions - Write a
CustomUser
class, subclassingUser
or copying its functionality.
The latter suggestion means that you would have to implement some things that User
does automatically manually, but I wonder whether that’s as bad as it sounds, especially if you’re at the beginning of your project. All you’d have to do is rewrite a middle-ware class and some decorators.
Of course, I don’t think this buys you anything that 1 won’t get you, except that your project shouldn’t break if you svn update
your django. It may avoid some of the compatibility problems with other apps, but my guess is most problems will exist either way.
- Unresolved import: models
- Django.db.models.loading.get_model vs. importing
- How can I pass kwargs in URL in django
- Validation using DeleteView before deleting instance
0đź‘Ť
There are anumber of ways to do this, but here’s what I’d do: I’d allow a user to enter an email, username (which must contain at least one letter and no @
symbols) or mobile number. Then, when I validate it:
- Check for the presence of
@
. If so, set it as the user’s email, hash it appropriately and set it as their username as well. - Check to see if it’s only numbers, dashes and
+
. Then, strip the appropriate characters and store it as both mobile number and username (if you’re storing the mobile number in another model for SMS purposes or something). - If it’s not either, just set it as username.
I’d also validate the user/phone/email field similarly on login and look in the appropriate place so that if, say, a user signs up with their mobile number and then changes their username (for some other purpose), they can still sign in with their mobile number.
- Django Full Text SearchVectorField obsolete in PostgreSQL
- ASGI_APPLICATION not working with Django Channels
- Exclude field from values() or values_list()