首页 文章

django中的自定义用户模型

提问于
浏览
13

我想使用djangodocs中所述的 django.contrib.auth.models.AbstractUser 创建自定义用户模型:

如果您对Django的用户模型完全满意并且您只想添加一些其他配置文件信息,则可以简单地继承django.contrib.auth.models.AbstractUser并添加您的自定义配置文件字段 . 此类提供默认用户的完整实现作为抽象模型 .

所以我在 Users 类中继承了 AbstractUser 类并添加了一个字段 . 但是当我运行 python manage.py syncdb 时,我收到以下错误:

CommandError: One or more models did not validate:
admin.logentry: 'user' has a relation with model login.users, which has either 
not been installed or is abstract.

我在stackoverflow上经历了其他问题,但无法解决错误 . 这是我的代码:

models.py

from django.conf import settings
from django.db import models
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import AbstractUser
from django.contrib import admin

class Users(AbstractUser):
    college = models.CharField(max_length=40)

admin.site.register(Users, UserAdmin)

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from login.models import Users
from django import forms

class UsersChangeForm(UserChangeForm):
    class Meta(UserChangeForm.Meta):
        model = Users

class UsersAdmin(UserAdmin):
    form = UsersChangeForm

    fieldsets = UserAdmin.fieldsets + (
            (None, {'fields': ('college',)}),
    )


admin.site.register(Users, UsersAdmin)

settings.py

INSTALLED_APPS = (
    'forms',
    'login',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

AUTH_USER_MODEL = 'login.users'

EDIT:

我想将用户信息存储在与 auth_user 相同的表中,而不是存储在新表中 .

3 回答

  • 1

    我在我的一个项目中做到了这一点 . 我很惊讶地看到你扩展了User因为the doc says something else :)你 can 扩展了Django用户模型,但是如果你只想添加新字段(不改变它的行为),你应该使用OneToOneField .

    If you wish to store information related to User, you can use a one-to-one
    relationship to a model containing the fields for additional information.
    

    因此,正如您在链接中看到的,您的代码应如下所示:

    from django.contrib.auth.models import User
    
    class MyUser(models.Model):
        user = models.OneToOneField(User)
    
        # Or a ForeingKey to the College table?
        college = models.CharField(max_length=40)
    
        other_data = ...
    
  • 3

    通过使用get_user_model()(以获取在项目中处于活动状态的User模型 . 在django.contrib.auth中定义)和AUTH_USER_MODEL(以引用User模型)而不是直接引用来保持代码通用是一个好习惯 . 用户模型 .

    from django.conf import settings
    
    class MyUser(models.Model):
        user = models.OneToOneField(settings.AUTH_USER_MODEL)
    
        # Or a ForeingKey to the College table?
        college = models.CharField(max_length=40)
    
        other_data = ...
    
  • 8

    尝试在 models.py 中删除此行:

    admin.site.register(Users, UserAdmin

    我发现了你的错误,你错误的顺序 INSTALLED_APPS 他们应该是下一个:

    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        #'django.contrib.sites',
        #'django.contrib.messages',
        'django.contrib.staticfiles',
        # Uncomment the next line to enable the admin:
        'django.contrib.admin',
        # Uncomment the next line to enable admin documentation:
        # 'django.contrib.admindocs',
        'login',
        'forms',
    )
    
    AUTH_USER_MODEL = "login.User"
    

    为什么?

    source code admin 使用用户模型所以你可以想:

    但我的用户模型是进入 login 应用程序,这一个是在管理员应用程序之前,因此在管理员之前安装 login ,为什么它不起作用?这是因为 django.contrib.auth 是可交换的(在你的情况下可以替换另一个模型已经可以通过login.User进行交换)所以当你创建一个新的用户模型时,django必须将其用户模型更改为新的用户模型然后你必须安装其余的 .

    How must be at the moment of run syncdb:
    
    
    1.- django.contrib.auth is installed, then this see if has been swapped, if yes it adds the new field or override completely the User Model (in your case only you add a field).
    
    2.- admin, contentypes.... your apps, are installed and all works.
    
    How you had it:
    
    1.- login is installed (where the new User Model was, you put the AUTH_USER_MODEL in settings)
    
    2.- Then forms.
    
    3.- Then django tries to install the admin app but it can't because auth_user table hasn't been added that's because django.contrib.auth was after admin, therefore there is no User Model, this one isnt's swapped and this throws the error  **admin.logentry: 'user' has a relation with model login.users, which has either 
    not been installed or is abstract.**
    

    因此,首先你必须安装 django.contrib.auth 应用程序,然后安装所有依赖的应用程序 .

相关问题