如何在Django中创建自己的用户模型,我希望我的P.K是用户名字段而不是Django自动生成的id字段?
我正在尝试以下方法:
我已创建userprofiles应用程序,我将在其中创建自定义django用户模型
INSTALLED_APPS = [
...
'userprofiles.apps.UserprofilesConfig',
...
]
AUTH_USER_MODEL = 'userprofiles.User'
在我的userprofiles/models.py
文件中,我定义了以下内容:
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
我使用AbstractBaseUser
class原因:
AbstractBaseUser提供了User模型的核心实现, 包括散列密码和标记化密码重置。你必须 然后提供一些关键的实现细节:...
以及I considered this explanation,其中说有必要手动添加我需要的字段。
然后,当我执行迁移时,我在User
模型中定义的字段(继承自AbstractBaseUser
)将在我的数据库中创建:
(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) ✗
然后我通过这种方式通过命令行界面创建了一个超级用户:
(fuupbol) ➜ fuupbol_project git:(master) ✗ python manage.py createsuperuser
Username: cdiaz
Email: cdiaz@fuupbol.org
Password:
Password (again):
Superuser created successfully.
(fuupbol) ➜ fuupbol_project git:(master) ✗
像Django一样,使用特殊表单在admin中相对于Users模型创建和编辑表单,因为这些只被认为是django原始用户模型。
这里我们使用带有AbstractBaseUser
的自定义django用户模型,然后我们使用以下类:
UserChangeForm
,因此这种方式应用于管理员用户表单,并且使用我之前修改后自定义的用户表单创建用户的UserCreationForm
在我的userprofiles/forms.py
文件中
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
在我的userprofiles/admin.py
文件中,创建一个CustomUserAdmin类,使用我在自定义用户模型中定义的字段进行自定义
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',)
然后当我去Django管理员并看到编辑已经创建的用户的选项时,我收到此消息:
目前我的用户模型中没有date_joined
属性,如果我将date_joined
属性添加到我的用户模型,并执行迁移,我收到以下消息:
(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) ✗
当我执行migrate
命令
(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) ✗
我无法理解错误消息django.db.utils.IntegrityError: column "date_joined" contains null values
的原因,因为此时我没有此属性date_joined
任何方向都将不胜感激。 感谢
答案 0 :(得分:1)
我假设您没有在任何实例上拥有date_joined数据,其中一个迁移要求它不为null。您可以进入数据库并添加手册以暂时绕过它。