3

How to can I create my own user model in Django, in which I want that my P.K be the username field and not the id field autogenerated by Django?

I am trying the following:

I've create the userprofiles application in where I will create my customize django user model

INSTALLED_APPS = [ ... 'userprofiles.apps.UserprofilesConfig', ... ] AUTH_USER_MODEL = 'userprofiles.User' 

In my userprofiles/models.py file I have defined the following:

from __future__ import unicode_literals from django.db import models from django.contrib.auth.models import AbstractBaseUser, UserManager, PermissionsMixin # Create your models here. class User(AbstractBaseUser, PermissionsMixin): GENDER_MALE = 'M' GENDER_FEMALE = 'F' GENDER_OTHER = 'O' GENDER_CHOICES = ( (GENDER_MALE, u'Male'), (GENDER_FEMALE, u'Female'), ) username = models.CharField(max_length=15, unique=True, db_index=True, primary_key=True) first_name=models.CharField(max_length=50, blank=False,) last_name=models.CharField(max_length=50, blank=False,) photo = models.ImageField(upload_to='avatars', blank=True) email = models.EmailField(max_length=254, unique=True) is_staff = models.BooleanField( default=True, help_text='Designates whether the user can log into this admin site.') is_active = models.BooleanField(default=True) #date_joined = models.DateTimeField(default=None) #date_joined = models.DateTimeField() gender = models.CharField( max_length=1, choices=GENDER_CHOICES, blank=False, ) is_player = models.BooleanField(default=False) is_coach = models.BooleanField(default=False) is_viewer = models.BooleanField(default=False) USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email',] objects = UserManager() class Meta: db_table = 'auth_user' def get_full_name(self): """ Returns the first_name plus the last_name, with a space in between. """ full_name = '%s %s' % (self.first_name, self.last_name) return full_name.strip() def get_short_name(self): "Returns the short name for the user." return self.first_name 

I am using the AbstractBaseUser class due to:

AbstractBaseUser provides the core implementation of a User model, including hashed passwords and tokenized password resets. You must then provide some key implementation details: ...

and also I considered this explanation in which say that is necessary add manually the fields that I needed.

Then, when I perform the migrations the fields that I've defined in my User model (that inherit from AbstractBaseUser) are created in my database:

(fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py makemigrations Migrations for 'userprofiles': 0013_auto_20160418_2252.py: - Add field groups to user - Add field user_permissions to user - Alter field is_superuser on user (fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py migrate Operations to perform: Apply all migrations: sessions, userprofiles, admin, contenttypes, auth Running migrations: Rendering model states... DONE Applying userprofiles.0013_auto_20160418_2252... OK (fuupbol) ➜ fuupbol_project git:(master) ✗ 

enter image description here

Then I've created a superuser via command line interface of this way:

(fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py createsuperuser Username: cdiaz Email: [email protected] Password: Password (again): Superuser created successfully. (fuupbol) ➜ fuupbol_project git:(master) ✗ 
  • In addition, I add these fields of my custom User model for that Django Admin can view them, of this way:

Like Django use special forms to create and edit forms in the admin relative to Users model, due to these was thinked only for the django original user model.

Here we are using a custom django user model with AbstractBaseUser, then we use the following class:

  • UserChangeForm which is applied to the User model, so this way is applied to the admin user form, and the UserCreationForm for that an user be created with from my user form customized with the previous modifications

In my userprofiles/forms.py file

from django import forms from django.contrib.auth.forms import (UserChangeForm,UserCreationForm) from .models import User class CustomUserChangeForm(UserChangeForm): class Meta(UserChangeForm.Meta): model = User class CustomUserCreationForm(UserCreationForm): class Meta(UserCreationForm.Meta): model = User 

In my userprofiles/admin.py file create an CustomUserAdmin class customized with the fields defined before in my custom User model

from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import User from .forms import CustomUserChangeForm, CustomUserCreationForm # Register your models here. class CustomUserAdmin(UserAdmin): form = CustomUserChangeForm add_form = CustomUserCreationForm fieldsets = UserAdmin.fieldsets + ( ( None, { 'fields':( 'username', 'password', 'first_name', 'last_name', 'gender', 'email', 'photo', 'is_staff', 'is_active', 'is_superuser', 'is_player', 'is_coach', 'is_viewer', 'last_login', ) } ), ) #Change our UserAdmin class to inherit of our CustomUserAdmin created above (do not inherit of model.ModelAdmin) @admin.register(User) class UserAdmin(CustomUserAdmin): list_display = ('username','password','first_name','last_name','gender','email','photo','is_staff','is_active','is_superuser','is_player','is_coach','is_viewer','last_login',) 

Then when I go to the Django admin and I see the options to edit some user already created, I get this message:

enter image description here

In this moment I do not have the date_joined attribute in my User model, and if I add the date_joined attribute to my User model, and perform the migrations, I get this messages:

(fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py makemigrations userprofiles Migrations for 'userprofiles': 0022_user_date_joined.py: - Add field date_joined to user (fuupbol) ➜ fuupbol_project git:(master) ✗ 

And when I execute the migrate command

(fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py migrate userprofiles Operations to perform: Apply all migrations: userprofiles Running migrations: Rendering model states... DONE Applying userprofiles.0015_user_date_joined...Traceback (most recent call last): File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) psycopg2.IntegrityError: column "date_joined" contains null values The above exception was the direct cause of the following exception: Traceback (most recent call last): File "manage.py", line 10, in <module> execute_from_command_line(sys.argv) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/core/management/__init__.py", line 353, in execute_from_command_line utility.execute() File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/core/management/__init__.py", line 345, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/core/management/base.py", line 348, in run_from_argv self.execute(*args, **cmd_options) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/core/management/base.py", line 399, in execute output = self.handle(*args, **options) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 200, in handle executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/migrations/executor.py", line 92, in migrate self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/migrations/executor.py", line 198, in apply_migration state = migration.apply(state, schema_editor) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/migrations/migration.py", line 123, in apply operation.database_forwards(self.app_label, schema_editor, old_state, project_state) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards field, File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 396, in add_field self.execute(sql, params) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 110, in execute cursor.execute(sql, params) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute return super(CursorDebugWrapper, self).execute(sql, params) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/utils.py", line 95, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise raise value.with_traceback(tb) File "/home/bgarcial/.virtualenvs/fuupbol/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) django.db.utils.IntegrityError: column "date_joined" contains null values (fuupbol) ➜ fuupbol_project git:(master) ✗ 

I cannot understand the reason of the error message django.db.utils.IntegrityError: column "date_joined" contains null values due to in this moment I do not have this attribute date_joined

Any orientation would be appreciated. Thanks

1
  • @electrometro It's real, you have the reason. I had the date_joined attribute in some initial migration as a not null. I've delete this migration and execute them again and all works. cldup.com/-70ZrvQnQq.jpeg Thanks a lot for the orientation :D Commented Apr 20, 2016 at 20:03

1 Answer 1

1

I am assuming you don't have data for date_joined on any of the instances and one of the migrations requires it to not be be null. You can probably either go into the database and add it manual to get around it temporarily.

Sign up to request clarification or add additional context in comments.

1 Comment

I am learning that when I want customize the django user model, is important know about of how to works their default user schema. I hope make some decumentation about it and compose step by step along that I go learning ..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.