Пользовательская модель пользователя в django

Я хочу создать пользовательскую модель пользователя, используя django.contrib.auth.models.AbstractUser как указано в djangodocs:

Если вы полностью довольны моделью Djangos User, и просто хотите добавить дополнительную информацию о профиле, вы можете просто подклассифицировать django.contrib.auth.models.AbstractUser и добавить свои собственные поля профиля. Этот класс обеспечивает полную реализацию Пользователя по умолчанию в качестве абстрактной модели.

Поэтому я унаследовал класс AbstractUser классе "Мои Users " и добавил поле. Но когда я запускаю 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 а не в новой таблице.

Ответы

Ответ 1

Я сделал это в одном из моих проектов. Я был удивлен, увидев, что вы расширили User, потому что документ говорит что-то еще. Вы можете расширить модель 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 = ...

Ответ 2

Рекомендуется использовать общий код с помощью get_user_model() (чтобы получить модель User, которая активна в вашем проекте. Определена в django.contrib.auth) и AUTH_USER_MODEL (для ссылки на модель пользователя), а не прямо ссылаться на модель пользователя.

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"

Зачем?

глядя на исходный код, администратор использует модель User, поэтому, может быть, вы можете подумать:

Но моя пользовательская модель входит в приложение для login в login, и она находится перед приложением администратора, поэтому login установлен до администратора, почему он не работает?. Это связано с django.contrib.auth что django.contrib.auth является swappable (модель может быть заменена на другую в вашем случае была заменена с помощью 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 because django.contrib.auth was after admin, therefore there is no User Model, this one isnt 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, а затем все приложения, от которых зависит.