【问题标题】:Custom user model in djangoDjango中的自定义用户模型
【发布时间】:2014-02-07 14:24:16
【问题描述】:

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

如果您对 Django 的 User 模型非常满意,并且只想 添加一些额外的配置文件信息,您可以简单地子类化 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'

编辑:

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

【问题讨论】:

  • 是命名联盟吗?除了class Users(AbstractUser):,你能试试其他型号名称吗
  • @Charlesliam 在将名称从User 更改为MyUser 并运行python manage.py syncdb 后,我收到一个新错误1146, Table stalker.login_myuser_user_permissions doesn't exist django
  • 您的用户相关权限的新表应该是 __user_permissions。我从你的陈述中相信了这一点。您的应用程序名称是login,您的型号名称是myuser。您可以尝试手动将表添加到您的数据库中。

标签: python django model-view-controller django-models


【解决方案1】:

我在我的一个项目中做到了这一点。我很惊讶你扩展了 User 因为the doc says something else :) 你可以扩展 Django User 模型,但是如果你只想添加新字段(而不是改变它的行为),你应该使用 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 = ...

【讨论】:

  • 其实我是想把它们和auth_user放在同一张表里
  • 在 Django 1.5 中你不需要额外的表来扩展用户表。
  • @Nil,你能检查一下这个问题吗? :) stackoverflow.com/q/36191737/3350765
【解决方案2】:

使用 get_user_model()(获取项目中活动的用户模型。在 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 = ...

【讨论】:

    【解决方案3】:

    尝试在 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 使用了 User 模型,所以也许你可以这样想:

    但是我的用户模型在 login 应用程序中,而这个在 admin 应用程序之前,因此 login 在 admin 之前安装,为什么它不起作用? .那是因为 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 应用程序,然后安装所有依赖的应用程序。

    【讨论】:

    • 我试过了,但是没有用,我得到了同样的错误信息
    • 您是如何订购 INSTALLED_APPS 的?授权后是管理员吗?
    • 是的,我按照你提到的方式订购了它
    • 表单应用程序中是否有用户外键?
    • @Victor,我使用AbstractUser 扩展了默认用户表。管理员运行顺利,但是当我在单击保存后尝试添加新用户时,我收到错误 ORA-00942: table or view does not exist,但我的 Oracle 数据库中有一个表,并且我的 Model.py 上有它。
    猜你喜欢
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    • 2014-01-04
    • 2021-04-15
    相关资源
    最近更新 更多