32

I am using the create_user() function that Django provides to create my users. I want to store additional information about the users. I tried following the instructions given at

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

but I cannot get it to work for me. Is there a step-by-step guide that I can follow to get this to work?

Also, once I have added these custom fields, I would obviously need to add / edit / delete data from them. I cannot seem to find any instructions on how to do this.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Gaurav Sharma
  • 4,032
  • 14
  • 46
  • 72
  • 2
    so *you* are the Django create_user() function? :) – ax. May 22 '10 at 05:03
  • 1
    I thought I was but unfortunately I am not :( .... Just a regular old human..Thanks for the grammar correction ax. Any idea on how to solve my actual problem? – Gaurav Sharma May 22 '10 at 05:20

5 Answers5

27

The recommended way is to create a new model and give it a OneToOneField() with the built-in User model like so:

class Student(models.Model):
    user = models.OneToOneField(User)
    college = models.CharField(max_length=30)
    major = models.CharField(max_length=30)

etc.

Then you can access the fields like this:

user = User.objects.get(username='jsmith')
college = user.student.college
rigdonmr
  • 2,662
  • 3
  • 26
  • 40
  • For me this produce a programmingError when I create a new user and I try to acces to it : "auth_student" does not exit. – T.Nel Jan 05 '17 at 11:27
  • 1
    Check this link, https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#extending-the-existing-user-model this is a more recent version – Jordy Cuan May 10 '17 at 01:17
24

I know It's too late and Django has changed a lot since then, but just for seekers,

According to Django documentation if you're happy with User model and just want to add some extra fields, do these:

1- Your models.py should be like this:

from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
    mobile = models.CharField(max_length=16)
    # if your additional field is a required field, just add it, don't forget to add 'email' field too.
    # REQUIRED_FIELDS = ['mobile', 'email']

2- add this to the setting.py

AUTH_USER_MODEL = 'myapp.CustomUser'

done!

Now you can run python manage.py syncdb

Sadegh
  • 2,669
  • 1
  • 23
  • 26
  • 5
    This solution works well, but I wouldn't recommend it because lots of libraries don't use the `AUTH_USER_MODEL` variable and assume you use the `User` object. – db0 Sep 19 '15 at 16:20
  • IMO in 2020+, and according to docs actually, that's th way to go. – logicOnAbstractions Apr 04 '22 at 15:01
19

I am not aware of a step by step(though I am sure a solid google would produce something). But here is a quick go at it.

1) Create a UserProfile model to hold the extra information and put it in your models.py. It could look something like this:

class UserProfile(models.Model):
    #required by the auth model
    user = models.ForeignKey(User, unique=True)
    middle_name = models.CharField(max_length=30, null=True, blank=True)

2) Tell your settings.py about the new class by adding this line (with the appropriate name):

AUTH_PROFILE_MODULE = "myapp.UserProfile"

3) Add a signal listener to create a blank UserProfile record when a new user is added. You can find a great snippet with directions here.

4) When processing the new user record you can populate the UserProfile record as well. Here is how I do the insert (notice the get_profile):

if (form.is_valid()):
    cd = form.cleaned_data
    user = User.objects.create_user(cd["UserName"], cd["Email"], cd["Password"])
    user.first_name = cd["FirstName"]
    user.last_name = cd["LastName"]
    user.save()
    #Save userinfo record
    uinfo = user.get_profile()
    uinfo.middle_name = cd["MiddleName"]
    uinfo.save()

That is all there is to it. This is not comprehensive, but should point you in the right direction.

Update: Please note that AUTH_PROFILE_MODULE is deprecated since v1.5: https://docs.djangoproject.com/en/stable/releases/1.5/#auth-profile-module

Bikash kharel
  • 472
  • 7
  • 16
Jason Webb
  • 7,938
  • 9
  • 40
  • 49
  • I've tried that. I get and error stating 'NoneType' object has no attribute '_default_manager'. – Gaurav Sharma May 22 '10 at 05:39
  • Created a file named UserProfile.py. Added the required code. Made changes in settings.py(AUTH_PROFILE_MODULE = 'app.UserProfile'). I get an error while trying to save the middle name i.e. at the line uinfo = user.get_profile() – Gaurav Sharma May 22 '10 at 05:54
  • You need to put the UserProfile in models.py. Then run `python manage.py syncdb` to apply to your database. Check your database to be sure that the table was actually created. Then try again. – Jason Webb May 22 '10 at 14:46
  • what kind of variable is form in your example? Is it based on some sort of ModelForm? – goelv Aug 11 '12 at 21:57
  • According to docs, user profile will be deprecated in 1.5 (for the more recent viewers) – Delos Chang Oct 17 '12 at 19:55
1

I arrived almost in 2023. Django at this moment is on 4.1.4...

If you want to extend User model without replacing it, following the django docs you can:

  1. Create proxy model based on User model if your changes are purely behavioral, and don't require change data.
  2. Use OneToOneField in a new model. This way you can add more fields to the existing User model:
from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=100)

This way you can query new fields from User model:

>>> u = User.objects.get(username='fsmith')
>>> freds_department = u.employee.department

If you want to tweak user's data in admin profile you can edit your admin.py this way:

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

from my_user_profile_app.models import Employee

# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
class EmployeeInline(admin.StackedInline):
    model = Employee
    can_delete = False
    verbose_name_plural = 'employee'

# Define a new User admin
class UserAdmin(BaseUserAdmin):
    inlines = (EmployeeInline,)

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
Rutrus
  • 1,367
  • 15
  • 27
-8

It's just another model. You manipulate it exactly the same way you manipulate every other model you come across.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 1
    Well, this one is used by Django directly and as can be seen from the answer by Sadegh, to use it you have to go to settings. This is not like other models. – Brambor Nov 22 '20 at 00:04