简体   繁体   English

django中的自定义用户模型

[英]Custom user model in django

I want to create a custom user model using django.contrib.auth.models.AbstractUser as stated in the djangodocs: 我想使用djangodocs中所述的django.contrib.auth.models.AbstractUser创建自定义用户模型:

If you're entirely happy with Django's User model and you just want to add some additional profile information, you can simply subclass django.contrib.auth.models.AbstractUser and add your custom profile fields. 如果您对Django的用户模型完全满意并且您只想添加一些其他配置文件信息,则可以简单地继承django.contrib.auth.models.AbstractUser并添加自定义配置文件字段。 This class provides the full implementation of the default User as an abstract model. 此类提供默认用户的完整实现作为抽象模型。

So I inherited the AbstractUser class in my Users class and added a field. 所以我在Users类中继承了AbstractUser类并添加了一个字段。 But when I run the python manage.py syncdb I get the following error: 但是当我运行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.

I went through other questions on stackoverflow but couldn't resolve the error. 我在stackoverflow上经历了其他问题,但无法解决错误。 Here is my code: 这是我的代码:

models.py 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 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 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: 编辑:

I want to store the user information in the same table as auth_user and not in a new table. 我想将用户信息存储在与auth_user相同的表中,而不是存储在新表中。

I did this in one of my project. 我在我的一个项目中做到了这一点。 I was surprised to see that you extended User because the doc says something else :) You can extend Django User model, but if you only want to add new fields (not change its behavior), you should use a OneToOneField. 我很惊讶地看到你扩展了User,因为doc说了别的东西 :)你可以扩展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.

So, as you can see in the link, your code should look like: 因此,正如您在链接中看到的,您的代码应如下所示:

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 = ...

It is a good practice to keep your code generic by using get_user_model() (to get the User model that is active in your project. Defined in django.contrib.auth) and AUTH_USER_MODEL (to reference the User model) rather than directly referring to the User model. 通过使用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 = ...

try removing this line in models.py : 尝试在models.py中删除此行:

admin.site.register(Users, UserAdmin ) admin.site.register(Users, UserAdmin

I figured out your error, You have the INSTALLED_APPS in the wrong order they should be the next: 我发现了你的错误,你的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"

Why? 为什么?

looking at the source code admin uses the User model so maybe you can think: 查看源代码 管理员使用用户模型,所以也许你可以想:

But my user model is into login app and this one is before admin app, therefore login is installed before admin, why it does not work?. 但我的用户模型是进入login应用程序,这个是在管理员应用程序之前,因此在管理员之前安装login ,为什么它不起作用? That's because django.contrib.auth is swappable (the model can be replaced for another one in your case has been swappable by login.User) so as you created a new User Model therefore django has to change its user Model to the new one and then you have to install the rest. 那是因为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.**

So accordingly first you always have to install the django.contrib.auth app and then all the apps that depends from. 因此,首先你必须安装django.contrib.auth应用程序,然后安装所有依赖的应用程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM