2014-01-18 5 views
13

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

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. This class provides the full implementation of the default User as an abstract model.

Так что я унаследовал 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' 

EDIT:

Я хочу сохранить информацию о пользователе в той же таблице, что и auth_user, а не в новой таблице.

+0

это коалиция имен? Можете ли вы попробовать другое название модели, кроме «class Users (AbstractUser)):' – Charlesliam

+0

@Charlesliam после смены имени с 'User' на' MyUser' и запущенного 'python manage.py syncdb', я получаю новую ошибку' 1146, Table stalker.login_myuser_user_permissions не существует django' –

+0

Ваша новая таблица для разрешения пользователя должна быть _ _user_permissions. Который я верил из вашего заявления. Ваше имя приложения - 'login', а ваше имя модели -' myuser'. Вы можете попробовать вручную добавить таблицу в свой db. – Charlesliam

ответ

8

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

На самом деле я хотел хранить их в той же таблице, что и 'auth_user' –

+0

. Вы должны изменить свой вопрос, чтобы добавить эту информацию. – Nil

+0

в Django 1.5 вам не нужна дополнительная таблица для расширения таблицы пользователей. – Charlesliam

1

попробуйте удалить эту строку в 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" 

Why?

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

Но моя модель пользователя в login приложения, и это один находится перед admin, поэтому 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 приложения, а затем все приложения, которые зависят от.

+0

Это сообщение было таким же, как и раньше –

+0

@ArchitVerma См. мой edit please –

+0

Я пробовал, но это не сработало, и я получаю то же сообщение об ошибке –

3

Рекомендуется использовать общий код с помощью 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 = ... 
Смежные вопросы