Blog Tags: 

Django User Profiles - Simple yet powerful

So you're building a web application, and using the excellent contrib.auth subsystem to manage user accounts. Most probably you need to store additional information about your users, but how? Django profiles to the rescue!

Django provides a lightweight way of defining a profile object linked to a given user. The profile object can differ from project to project, and it can even handle different profiles for different sites served from the same database.

In a nutshell, using Django profiles consists of 3 steps:

  • Define a model that holds the profile information.
  • Tell Django where to look for the profile object.
  • Create the user profile as needed.


Defining the user profile model

The only requirement Django places on this model is that it have a unique ForeignKey to the User model, and is called user. Other than that, you can define any other fields you like.

For our example, we'll create 2 user profile fields (url and company).


from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    url = models.URLField("Website", blank=True)
    company = models.CharField(max_length=50, blank=True)


Tell Django about the profile object

Accessing a users profile is done by calling user.get_profile(), but in order to use this function, Django needs to know where to look for the profile object.

This is defined in the projects file.

AUTH_PROFILE_MODULE = "account.UserProfile"

Important note: The settings value is appname.modelname, and not appname.models.modelname as you might expect. The reason for this is that Django is not doing a direct import, but using an internal model-loading function.

Once defined, and if the profile exists, accessing a users profile is simple.


def view_foo(request):
    user_profile = request.user.get_profile()
    url = user_profile.url

    url = request.user.get_profile().url


Create the user profile as needed

Notice in the section above I mentioned "if the profile exists". This is because the get_profile() function will raise a DoesNotExist exception if the profile does not exist.

One of the common solutions to this issue is to create the profile when a user is registered using a signal (see my post on Django Signals).

Another option is catch the exception, and redirect the user to a profile creation form. You usually want to do this if the profile fields are mandatory.

My personal favorite though, is to have the profile created automatically when referenced, with the added bonus of being able to reference a users profile as user.profile instead of user.get_profile()


class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])


To reiterate, including the above enables us to reference the users profile with cleaner code, and have it created if it does not exist.


def view_foo(request):
    url = request.user.profile.url


Ever needed to store additional user information? Post a comment!

You can get future posts delivered by email or good old-fashioned RSS.
TurnKey also has a presence on Google+, Twitter and Facebook.


cico's picture

Hi Alon, thanks for the interesting and clear post!

I'm currently trying to write a django application that should be based on more than one user profile.. How would your solution coexist with an abstract base-profile? Subclasses could be handled (and attached) on creation with signals or with the (very nice!) User.profile function, but what about the base one?

Thank you very much,


Alon Swartz's picture

Thanks for the feedback. I'm not quite sure what you mean, Django User Profiles are a simple way to associate additional information to your user accounts. If you need to associate other models to a user account, then you should use a foreign key.


from django.db import models
from django.contrib.auth.models import User

class Foo(models.Model):
    user = models.ForeignKey(User)
    stuff = models.CharField(max_length=50)

You could then refer to the associated user foo's with something like this:


from django.contrib.auth.decorators import login_required

def bar(request):
    foos = request.user.foo_set.all()  # or any of the other useful methods

I hope the above helps, if not, the more info you can provide, the easier it will be to help.

Antoin O O Lachtnain's picture

That example really helped me do what I wanted to do. Thanks. 

Stodge's picture

Why do Django profiles exist when you can just define another model with a foreign key to the user model? Is it simply to define a standard profiling system? It seems odd that it re-creates a profile model with a foreign key yet forces you to use a function to retrieve it (get_profile) instead of just giving you: user.profile.


Thanks, Mike

reverse phone lookup's picture

I am sure django is powerful and quite useful. The applications in “contrib.” package are very tempting.Especially the tools for generating rss and atom feed.But django is not free from problem. It just isn’t effective enough. It lacks a bit on creating boundary pushing models effectively. Is it possible to use sphinx for our documentation is this tool compatible with django? I have read some where piston is very useful in creating API’s. Is it so?

Liraz Siri's picture

Most of the comments that try to take advantage of the Drupal comment external backlink are posted by automated spam bots. We usually delete those immediately. But your response is eerily relevant to the discussion so I suspect you may be a human.

Please don't take offense. As far as I'm concerned you're welcome to join the community even if you are a bot - so long as you can pass my turing test and respond appropriately.

TurnKey welcomes all sentient beings.

Guest's picture

Nice. I like when administrators or moderators treat comments in such a way.

Rapid Prototyping's picture

Well, it has been some time since I have been looking out for something like this. I often indulge in building web applications and I too use the same subsystem contrib.auth for the purpose of managing my accounts. Things are really great, to be honest, except for the fact that I have to store extra information regarding the users. Anyway, since I started using Django, things have really been great from then on! The fact that it provides a really easy way of defining things is why I found it handy!

ryan's picture

Hi Alon,

What is the python-level code for creating users' profiles? In the shell, whenever I type "p=User.objects.get(username='xxxx').get_profile" followed by "p.attribute1", I receive a "'User' object has no attribute 'attribute1'.

Any suggestions for creating the profile to make sure this attribute "registers"? Thanks!

Alon Swartz's picture

get_profile is a function, so you need to call it. Using your example you would do something like this:

from django.contrib.auth.models import User

p = User.objects.get(username="xxxx").get_profile()  # notice the ()
print p.attribute1

But, depending on your code and what you want to do, I would recommend re-reading the code snippets in the blog post, and use user.profile.attribute instead, it's more elegant.

ryan's picture

Hi again Alon, Thanks for your earlier reply. I'm getting back to Django after a long holiday vacation (I hope you enjoyed one too!), and I revisited your answer.

I think I figured out my problem, and I thought it may be helpful for others if I post this here. Also, I welcome your thoughts on my quick-and-dirty/DIY/band-aid fix.

I realized that setting up profiles according to your instructions doesn't actually create profiles for pre-existing users. So when typing "get_profile()" it always returned an error, even though I knew the users existed and had attributes.

In response to my own question, I figured out how to create user profiles for pre-existing users. First is assigning the user object: "u=User.objects.get(username="xxxx")". Then you must type: "u.userprofile_set.get_or_create(field1=foo, field2=bar, attribute3=foobar)". This creates the profile with the assigned field values.

Of course, this could all be done in a view. And it could also be re-coded to match your elegant suggestion. But this at least is how I got it to work code-level.

One question, though: do you know of a way to update the values once they're set?

Thoughts? Suggestions (other than for elegance)?

Thanks again, Alon!

Alon Swartz's picture

Glad you got it sorted. Take another look at account/ in my original post - it will get the profile if it exists or create it when it doesn't.

Regarding updating values, it's a regular model, so once you have the user/profile object, just update the values and call save().

mart's picture

Thank you for your explanations but what's the way to create a new custom user then ?

I guess I should first create the "normal" user (using User.objects.create_user(,,)) and then the extended one using the foreign key to the newly created user. When I'm using the shell to do it, I've got an error with the first command that the first of my custom field is required...

mart's picture

Ok forgot what I said, I put some code I found here that I guess is wrong

Alon Swartz's picture

If you want to manually create a user account you could do it like the following snippet, and then extend the user using the profile method described in the post. But, you might want to use the registration app (and tweak or extend it using signals) - depending on your use case.

user = User.objects.create_user('username', '', 'password')

If you have a specific question, or a piece of code isn't working, please post it here together with your as it will be a lot easier to help.

Here's picture

I love the option of creating a user profile. It really makes a site look professional, and keeps out the riffraff. I don't develop anything without this option.

Yurietc's picture


I have created user profile, but what about the additional table "maApp_userprofile" in my database ? The DatabaseError (1146, "Table 'myApp.myApp_userprofile' doesn't exist") is occurs. And " syncdb" does nothing. How this table must be created ?

DebT's picture

I'll need to check out Django now. Looks simple enough.

Guest's picture

Thanks for the useful post!  Where I am still stuck is trying to figure out how to create test users through a command.  For example, if I have an app:







and I follow your lead in



class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])


What would I put in to create a test user with a username of Bob, no age given, and a display name of Bob Smith?  So far, everything I have tried han't actually resulted in the UserProfile which is attached to the user actually being updated in the database.




Alon Swartz's picture

You really should look into using a contrib module to handle user creation for you (such as django-registration), but I suppose it depends on your use-case.

Anyway, hopefully the below code snippet will help you get started.

user = User.objects.create_user('bob', '', 'password')
user.first_name = "Bob"
user.last_name = "Smith"

user_profile = user.get_profile()
user_profile.display_name = "Bob Smith"

My guess is you forgot to call save() on the object you created, which is required to write the changes to the database.

Also note that I used first_name and last_name as an alternative to "display_name", that's usually how you store account names in Django, you can then access the fullname like this:


I hope the above helps...

mohamed's picture

Hey, (sorry for my english :-( )

Thanks for this posts !

I want to add the Field 'Bureau'  the user.

I do the same things in your post ;)

But I don't have the field 'Bureau' in the back-end of the site ??!!


Roland S's picture


Hi Alon,

I've read quite a bit about creating users and it all seems to make sense until I go to make them myself.  I find I am missing some crucial bit of information to make it all work.

Here is what I think I should do to set up a user accounts:


1. Create app called 'accounts'

2. In accounts/, create a model for the 'base' user information; username, password, email

3. In accounts/, create a second model for the detailed user information; first & last name, favourite colour, etc.

4. In accounts/, create functions for new user registration, login, logout, etc.

5. In ../, set AUTH_PROFILE_MODULE = ('accounts.baseUser',)

6. In ../, link views to templates

7. In ../templates/registration/accounts make template files for login, etc.


Is step 2 correct or should this 'base' user model be handled by contrib.auth.models?  In otherwords, do I just need to worry about making models for the extended information and link it to contrib.auth.models.User?


You may guess that I am new to Django and obj-oriented programming.  I have gone through the  Can you share a link to an example where someone sets up the user models, registration, login from scratch as opposed to snippits that I have to figure out how to reassemble?

Alon Swartz's picture

You don't need step 2, actually you must not do anything like step 2 if you want to use contrib.auth

You also don't need to create first/last name fields as you mentioned in step 3 as contrib.auth.models.User already has them. See my comment above for more details on that.

You also don't need step 4, contrib.auth handles that for you.

Regarding step 5, I'm don't think using a tuple will work. It should be a string, see the post for an example.

I'd recommend re-reading the post a couple of times, and if something isn't clear let me know and I'll elaborate. If something isn't working, feel free to ask and include code snippets.

Roland S's picture

Thanks, Alon.  Your response helps to clarify.  I will reread.  


Roland S's picture

Hi Alon,

I got rid of the user models I built before and am now relying on the built in user model.  I built an app called msgboard that has the following model:


from django.db import models
from datetime import datetime
from django.contrib.auth.models import User
class FindMsg (models.Model):
    msg = models.TextField(max_length=500)
    pub_date = models.DateTimeField('date published')
    author = models.ForeignKey(User)
    def __unicode__(self):
        return self.msg
I have my admin site installed and it is working; I can add users.  However, the author = models.ForiegnKey(User) in the model causes the error below when I load admin/msgboard/findmsg in my browser but if I get rid of that line, it works.  Also interesting is that the 'author' line does not cause admin/msgboard/findmsg/add to fail; ie author shows up as a form item as it should.
Here's the browser error:
DatabaseError at /admin/msgboard/findmsg/
no such column: msgboard_findmsg.author_id
Request Method: GET
Django Version: 1.3
Exception Type: Database Error
Exception Value: no such column: msgboard_findmsg.author_id
Any ideas?
Roland S's picture


Very interesting.  I created a new project from scratch to try it again and it worked this time. The problem, I believe, was that I corrupted the original project's admin site by attempting to define my own User models.  I guess this causes irreparable corruption or, at least, I don't know how to fix it. 


Ferguzz's picture

The only problem with this is that there is no profile caching like with get_profile().  So if you were to do something like...

    user.profile.some_field = some_value

the user profile would not be updated!

Reiner Marquez Alvarez's picture

this solution is pretty but it needs caching.

def get_profile(u):
    if not hasattr(u, '_profile_cache'):
        u._profile_cache = UserProfile.objects.get_or_create(user=u)[0]
    return u._profile_cache
User.profile = property(get_profile)
And now, we have no inconvenients
Ravi's picture

I am very new to the Django. Can you help me to design a Django project which will create the user and their profiles. But I dont want to use default admin Django model. And these are accessable without admin login.

val's picture

What do you think of the ForienKey approach in combonation with a "User" post_save creation of the "UserProfile"? The following app is pluggable and takes care of all of that for you.

Mind you that the UserProfile class still needs to be created by developers and the delete() method on the UserProfile has to be updated to delete any non-user FK, M2M ... etc.

This the ForienKey approach recommended by James Bennette the release manager of Django.

Truth About Abs's picture

I was facing problem of creating profile.But your instructions helped me a lot.Thanks.

Szubi's picture


I'm building Django app on top of an existing database (MS SQL). I have to access some existing data in that database, so as a UserProfile model I've used an exitsting table. Everything works as expected, but using MSSQL and Apache on Windows drives me to a lot of problems so I decided to move to Linux + Apache + Postgres database - MyApp specific models will be handled by postgres database, but I still need to have access to for example MSSQL UserProfile table. Is there any way to do that? No success till now :-(



DF's picture

Great info. But was wondering how to create a url to display the users profile along with a way for a user to add their own profile info with a form. Once a form is created from the UserProfile model, what kind of view would be required and accompanying url for that (would the id be user_id or profile_id)?

I'm trying to incorporate profiles from scratch as django-profiles is quite confusing and I'm kind of stuck at the point where profiles are automatically created when a uuser registers, but I want to not only display these, but also have a user able to input the detailed profile info on their own through a form.

Any help greatly appreciated as I've been at this for hours.

Szubi's picture



(r'^settings/$', user_settings),  
    (r'^settings_changed/$', direct_to_template, {'template':'form_changed.html',
    'extra_context':{'message':'Settings has been changed','next':'/settings/'}}), 

Somewhere in

def user_settings(request):
    c = {}
    user = request.user
    profile = user.profile
    if request.method == 'POST': # If the form has been submitted...
        form = UserprofileForm(request.POST,instance=profile) # A form bound to the POST data
        if form.is_valid(): # All validation rules pass
            # Process the data in form.cleaned_data
            # ...
            return HttpResponseRedirect('/settings_changed/') # Redirect after POST
        user = request.user
        profile = user.profile
        form = UserprofileForm(instance=profile) # An unbound form
    return render_to_response('settings.html', locals(),context_instance=RequestContext(request))


class UserprofileForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ('show_thumbnails','interface','style') #put fileds You want user to edit here

    def clean(self): # add custom validation here
        cleaned_data = self.cleaned_data
        interface = cleaned_data.get("interface")
        st  = cleaned_data.get("show_thumbnails")
        if field_interface_does_not_pass_validation_rules:
                # We know these are not in self._errors now (see discussion
                # below).
                msg = u"Invalid input blah blah!!"
                self._errors["interface"] = self.error_class([msg])

                # These fields are no longer valid. Remove them from the
                # cleaned data.
                del cleaned_data["interface"]

        # Always return the full collection of cleaned data.
        return cleaned_data


{% extends "base.html" %}
{% block title %}Title text{% endblock %}
{% block content %}
{% if form.errors %}
<p class="error">Invalid input</p>
{% endif %}
<form method="POST" action="/settings/">
{% csrf_token %}
<table class="entryTable">
{{ form.as_table }}
<tr><td class="buttons" colspan="2">
<input type="button" class="button" value="Cancel" onclick="location.href='/0/';"/>
<input type="submit" class="button" value="Submit"/>
{% endblock %}

That all ;-)


dpbklyn's picture


Can you please walk me through the URLs file you mention above, I am not sure I understand what each part does.

Thank you,


David Phillips's picture

Hello Alon and THANK YOU!!!

If I found this post last week it would have saved me about 5 days worth of coding and trobleshooting--THANK YOU!

I am new to Django and I am trying to set up a view that uses a reverse lookup in a url.  How can I pass the the User's ID number to a url so the user moves from one form on his account (User Information) to another form on his account where he inputs information directly related to his account?

def regPage(request):
    form = RegForm(request.POST)
    # Save new/edited pick
    if request.method == 'POST' and form.is_valid():
        return HttpResponseRedirect(reverse('league_page', args=(), kwargs={ 'id' : id }))
        #return HttpResponseRedirect('/dev/leaguepage/')
    user_info = UserRegistration.objects.all()
    context = {
        'user_info' :user_info,

    return render(request, 'regpage.html', context)

def leaguePage(request, id):

    form = LeagueForm(request.POST or None instance=id and LeagueRegistration.objects.get(id=id))

    # Save new/edited pick

    if request.method == 'POST' and form.is_valid(): return HttpResponseRedirect('/draft/') league_info = LeagueRegistration.objects.all() context = {

        'form':form, 'league_info' :league_info,

    return render(request, 'leaguepage.html', context)

urlpatterns = patterns('',



    url(r'^user/(?P<id>\d+)/$','acme.dc_django.views.leaguePage', name="league_page"),

    url(r'^$', 'acme.dc_django.views.regPage'),


Please not the above code doesn't work.  This is the code I have been troubleshooting.

Thank you,



dpbklyn's picture

I am steppig through your process and it is all (slowly) becomming clear to me.

Shabda Raaj's picture

If I understand you correctly, you will need to customize the form and pass the user_id. We have written more about it here.

Something like this.

1. Customize the __init__ in the form, pass user_id to __init__.

2. Use wherever needed.

Greg's picture

Was just wondering how to do this and a google threw this up.

I didn't know about the django user profile option and would have reinvented the wheel.

This was very helpful.

p sai prasanth's picture

thanks for the nice information. 

newbie's picture

ok i want that the user who clicks the login button gets directed to his home page which contains his profile can i do that??

and also tell me what changes(if any) do i need to make in the url patterns.......i m new to i want a straightforward approach.......pls help!!

pls tell me the whole process...i ve made the login page already.

Greg's picture

Sorry, I'm very new to Django, so please forgive the silly question! And thanks for this excellent guide.

If request.user is passed all over the place, would creating a largish dictionary in this way (say, all the pages a user has ever visited on the site) be bad practice, since as part of the user, the big dictionary is getting passed around too? Or does the foreign key solve the problem in some behind-the-scenes way?

Francisco André's picture

Hello, I need storing fields extra about my users and I have followed documentation but not see how persist a object in and I not render the forms on template html.
Please, any help me?
tushar.pucsd's picture

Hello, I am new to django and just start to work with a application.

I want to add custom field to auth_user table

I have a TrustAdministration Model

from django.contrib.auth.models import User

class Trust(models.Model):


class TrustAdministration(models.Model):
   trust = models.ForeignKey(Trust)
  user = models.OneToOneField(User)  # Relation with inbuilt User table
  first_name = models.CharField(max_length=200)
  last_name = models.CharField(max_length=200)
  mobile_number = models.CharField(max_length=10)
  landline_number = models.CharField(max_length=13)
  email = models.CharField(max_length=50, blank = False)
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from models import Trust, TrustAdministration
class TrustAdministrationForm(forms.ModelForm):
 class Meta:
   model = TrustAdministration
class UserCreateForm(UserCreationForm):
  class Meta:
    model = User
On my form display's all the entries of TrustAdministration and Username, password1 and password2
def trust_registration(request):
  if request.POST:
     trust_form = TrustForm(request.POST, instance=Trust())
     trust_admin_form = TrustAdministrationForm(request.POST, instance=TrustAdministration())
    user_form = UserCreateForm(request.POST)
   if user_form.is_valid():
     username = request.POST['username']
     password = request.POST['password']
     new_user = User.objects.create_user(username=username, password=password)
     new_trust =
     new_trust_admin = = False) = new_trust
     new_trust_admin.user = new_user = username
      return HttpResponseRedirect('/registration/trust_registration')
  return HttpResponseRedirect('/registration/trust_details')
   trust_form = TrustForm()
   trust_admin_form = TrustAdministrationForm()
   user_form = UserCreateForm()
  return render(request, 'trust/trust_registration.html', {'trust_form': trust_form,
                                                                                     'trust_admin_form' : trust_admin_form,
                                                                                     'user_form' : user_form})
When i submit the form it will give error password is required, but usercration form shows inputfield for username, paassword=password1, and confiramtion Password = password2  
Claus Conrad's picture

Thank you for this very clear article about adding user profiles in Django, it was very helpful and easy to follow. Even though 4 years have gone by it appears to work just as well using Django 1.7b1 :)

Sudipta Sen's picture

Please go through the question sir. Your post helped me a lot, but I am stuck here badly. No clue.

JOB OFFER's picture

Applications are invited from suitably qualified persons for full time appointments to the following positions in the Nigeria Customs Service. Candidates must possess the qualification stated against the respective positions:
1.) SUPERINTENDENT CADRE: Nigeria Customs Service Post: Assistant Superintendent of Customs Grade II – Consol 08 Entry Qualification: Candidates must possess a Bachelors Degree with at least Second Class Lower Division from a recognized University.
2.) INSPECTOR CADRE Post: Inspector of Customs – Consol 07 Entry Qualification:- Higher National Diploma (HND) with at least lower credit from a recognized Polytechnic.
(ii) Assistant Inspector of Customs – Consol 06 Entry Qualifications: - National Diploma (ND) with at least lower credit from a recognized Polytechnic, National Certificate of Education (NCE),
3.) ASSISTANT CADRE Post: (i) Customs Assistant II – Consol 04 Entry Qualifications: - Senior Secondary Certificate Examination (SSCE) with Credits in not less than five subjects including English Language and Mathematics obtained at a maximum of two sittings. General Certificate of Education (GCE) Ordinary Level with credit in five subjects including English Language and Mathematics obtained at a maximum of two sittings,
(ii) Customs Assistant III – Consol 03 Entry Qualifications: - Senior Secondary Certificate Examination (SSCE) with Credits in not less than four subjects including English Language obtained at a maximum of two sittings. General Certificate of Education (GCE) Ordinary Level with credit in four subjects including English Language obtained at a maximum of two sittings.
* Form fee is N7000 only
* Registration fee   N2000
* Registration Number and pin for registration will be sent to your Email after payment.
* All Applicants must be citizens of Nigeria using the Nigeria Voters Card as proof.
* Applicants shall be of Nigerian origin by birth.
* All Applicants must attend zonal screening exercise at the designated zonal centre for their respective states.
* Non-Tradesmen & Women Applicants must be aged between 18 – 35 years by 15 February 2014.
* Tradesmen & Women Applicants must be aged between 18 – 35 years by 15 February 2014.
* Applicants must be medically, physically, and psychologically fit and must not be less than 1.65 meters tall for men and 1.56 meters for women.
* Applicants must be free of any Criminal conviction.
For more information on Payment and Registration:
Name: Mr. Dorian
Phone: +2347031991061


sara's picture

what should i do with this error ?

User' object has no attribute 'get_profile'


Post new comment