Django's auth
module provides all user accounts with a User
object. The User
model can be found in django.contrib.auth.models
. It provides a number of basic user functionalities, including storage of a name, e-mail address, and access privileges—as in whether the user is a staff member, has an active account, or is a super user. It also records when the user signed-up for an account and when they last logged-in.
For an e-commerce application, the default set of information stored by Django for each user is useful, but likely not enough. For example, any web store that needs to ship its product to their customers will want to store the customer's mailing address. The User
model does not include a field for mailing address, nor does it include phone numbers, birthdays, or a lot of other information that might be useful.
This is an intentionally minimalistic design on Django's part. Instead of trying to predict what fields Django developers require, the decision was made to provide a simple method of extending the Django User
model. This way the application developers can create whatever representation of additional user data they need and attach it automatically to Django's built-in User
model.
Extending this user information is very simple: write your own model with a ForeignKey
to the User
model and whatever extra data attributes you require. This is called a profile model. When you have built this model, you can tell Django about it using a special setting: AUTH_PROFILE_MODULE
. This setting will point to your custom extension model using the app.model
syntax. For example, if your app is called myapp
and this app contains a model called UserProfile
, you would refer to it as the string 'myapp.UserProfile'
.
By creating this setting, you automatically enable a built-in feature for each User
object: the get_profile()
method. This method automatically returns an instance of your profile model specific to the User
object you're working with. You can even access profile fields using dot-notation like so: user_object.get_profile().address1
.
Note that when a User
object is created, by a new user registering an account, a corresponding profile model is not automatically created. You must create it yourself. The best way to accomplish this is to use Django's signals feature and write a handler to listen for django.db.models.signals.post_save
on the User
model. This would look something like this:
fromdjango.db.models.signals import post_save fromdjango.contrib.auth.models import User frommyapp.models import UserProfile defprofile_creation_handler(sender, **kwargs): instance = kwargs['instance'] profile, created = UserProfile.objects.get_or_create(user=instance) post_save.connect(profile_creation_handler, sender=User)
Django uses signals to send messages from one piece of code to any other piece, which is called "listening". In the previous source code, we were setting up a listener, or handler, called profile_creation_handler
. This handler function will run every time Django sends the post_save
signal. But this particular handler will ignore any post_save
signals that are not sent by a User
object, as specified by the sender
keyword argument in the connect
call. The connect
method is how we attach handlers to a specific signal. Django's documentation includes an explanation of the signal system and a full list of all built-in signals.