2014-01-08 92 views
3

我一直在關注this guide以在Django中創建自定義用戶模型。我是Django的新手,並且在試圖按照第8步使用south構建遷移時遇到了一系列的四個錯誤。創建Django自定義用戶模型時的關係錯誤

的錯誤是:

auth.user: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'. 
auth.user: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'. 
member.customuser: Accessor for m2m field 'groups' clashes with related m2m field 'Group.user_set'. Add a related_name argument to the definition for 'groups'. 
member.customuser: Accessor for m2m field 'user_permissions' clashes with related m2m field 'Permission.user_set'. Add a related_name argument to the definition for 'user_permissions'. 

我理解的是多對多的關係問題,我相信由PermissionsMixin引起的。雖然我不是100%確定的。

這是我的自定義模式:

class CustomUser(AbstractBaseUser, PermissionsMixin): 
    email = models.EmailField(_('email address'), max_length=254, unique=True) 
    first_name = models.CharField(_('first name'), max_length=30, blank=True) 
    last_name = models.CharField(_('last name'), max_length=30, blank=True) 

    is_staff = models.BooleanField(_('staff status'), default=False, 
            help_text=_('Designates whether the user can log into this admin site')) 
    is_active = models.BooleanField(_('active'), default=True, 
     help_text=_('Designates whether this user should be treated as active. Unselect this instead of deleting accounts.')) 

    date_joined = models.DateTimeField(_('date joined'), default=timezone.now) 

    objects = CustomUserManager() 

    USERNAME_FIELD = 'email' 
    REQUIRED_FIELDS = [] 

    class Meta: 
     verbose_name = _('user') 
     verbose_name_plural = _('users') 

    def get_full_name(self): 
     full_name = '%s %s' % (self.first_name, self.last_name) 
     return full_name.strip() 

    def get_short_name(self): 
     return self.first_name 

    def email_user(self, subject, message, from_email=None): 
     send_mail(subject, message, from_email, [self.email]) 

而定製的用戶管理:

class CustomUserManager(BaseUserManager): 
    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields): 
     now = timezone.now() 

     if not email: 
      raise ValueError('The given email must be set') 

     email = self.normalize_email(email) 
     user = self.model(email=email, is_staff=is_staff, is_active=True, is_superuser=is_superuser, last_login=now, date_joined=now, **extra_fields) 
     user.set_password(password) 
     user.save(using=self._db) 
     return user 

    def create_user(self, email, password=None, **extra_fields): 
     return self._create_user(email, password, False, False, **extra_fields) 

    def create_superuser(self, email, password, **extra_fields): 
     return self._create_user(email, password, True, True, **extra_fields) 

Models.py進口:

from django.db import models 
from django.utils import timezone 
from django.utils.http import urlquote 
from django.utils.translation import ugettext_lazy as _ 
from django.core.mail import send_mail 
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager 

我也創建了自定義窗體和自定義管理員位,就像教程一樣,但不相信他們與這個問題有關。如果需要,我很樂意將它們包含在內。

Pip freeze

pip freeze 
Django==1.6.1 
South==0.8.4 
argparse==1.2.1 
coverage==3.7.1 
distribute==0.6.24 
django-form-utils==1.0.1 
djangorestframework==2.3.10 
psycopg2==2.5.1 
wsgiref==0.1.2 

Settings.py

# Build paths inside the project like this: os.path.join(BASE_DIR, ...) 
import os 
BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 

# Application definition 

INSTALLED_APPS = (
    'django.contrib.admin', 
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    'rest_framework.authtoken', 
    'rest_framework', 
    'south', 
    'log_api', 
    'member', 
) 

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', 
) 

ROOT_URLCONF = 'server_observer.urls' 

WSGI_APPLICATION = 'server_observer.wsgi.application' 

# Internationalization 
# https://docs.djangoproject.com/en/1.6/topics/i18n/ 

LANGUAGE_CODE = 'en-GB' 

TIME_ZONE = 'Europe/London' 

USE_I18N = True 

USE_L10N = True 

USE_TZ = True 


# Static files (CSS, JavaScript, Images) 
# https://docs.djangoproject.com/en/1.6/howto/static-files/ 

STATIC_URL = '/static/' 

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"), 
) 

# Where to look for templates 

TEMPLATE_DIRS = (
    os.path.join(BASE_DIR, "templates"), 
) 

# Custom user model 

#AUTH_USER_MODEL = 'member.CustomUser' 
AUTH_USER_MODEL = 'auth.User' 

# Quick-start development settings - unsuitable for production 
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ 

# SECURITY WARNING: keep the secret key used in production secret! 
SECRET_KEY = '' 

# SECURITY WARNING: don't run with debug turned on in production! 
DEBUG = True 

TEMPLATE_DEBUG = True 

ALLOWED_HOSTS = [] 

# Database 
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases 

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.postgresql_psycopg2', 
     'NAME': 'server_observer', 
     'USER': '', 
     'PASSWORD': '', 
     'HOST': '127.0.0.1' 
    } 
} 

我已經嘗試設置AUTH_USER_MODEL = 'member.CustomUser'AUTH_USER_MODEL = 'auth.User'爲好。

我被卡住了,在這最後一晚已經花了很長時間了。我會非常感謝任何建議。

+0

我想說AUTH_USER_MODEL是這裏的問題,它肯定應該指向你的CustomUser,應防止auth.User從不斷被創建。 –

+0

我有一個在生產環境中運行的API,所以我希望能夠在不丟失任何記錄的情況下遷移到新的用戶模型。 –

+0

API使用外鍵將自己與每個用戶進行關聯。有沒有辦法將所有這些遷移到新的用戶模型?如果我不得不放棄它,那不是世界末日,但我不想。 –

回答

2

您必須在settings.py中聲明AUTH_USER_MODEL。你的情況:

AUTH_USER_MODEL = 'member.customuser'