簡體   English   中英

Django - 為用戶指定的未知字段(組)

[英]Django - Unknown field(s) (groups) specified for User

當我嘗試進行 makemigrations 和遷移時,我遇到了這個錯誤。 我創建了一個自定義用戶模型,在遷移時我遇到了這個問題。 我只有在將“AUTH_MODEL_USER = account.User”添加到 settings.py 時才會遇到這個問題,沒有這個我可以遷移代碼。

筆記:
1)在創建自定義用戶之前,我使用 wagtail 做了一些實驗,所以為了做實驗,我創建了超級用戶,我不知道這個問題是否是因為在創建自定義用戶模型之前創建了超級用戶。
2) 我還沒有在 admin.py 和 form.py 中添加任何代碼,我想在輸入任何其他代碼之前檢查我是否能夠遷移代碼。

帳戶/模型.py

    from django.db import models
from django.utils import timezone
from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager
)

class Program(models.Model):    
    program_name = models.CharField(max_length=20, null=False)
    program_start_date = models.DateField(null=False, blank=False)
    program_end_date = models.DateField(null=False, blank=False)
    created_date = models.DateTimeField(default=timezone.now, blank=True)
    updated_date = models.DateTimeField(auto_now_add=True, null=True)

    def created(self):    
        self.created_date = timezone.now()
        self.save()

    def updated(self):    
        self.updated_date = timezone.now()
        self.save()

    def __str__(self):    
        return str(self.program_name)

class UserManager(BaseUserManager):    
    def create_user(self, email, password=None, is_active=True, is_admin=False, is_staff=False):    
        if not email:    
            raise ValueError("User must have an Email Address")
        user_obj = self.model(
            email = self.normalize_email(email)
        )
        user_obj.set_password(password) # Changing the user password
        user_obj.active = is_active
        user_obj.staff = is_staff
        user_obj.admin = is_admin
        user_obj.save(using=self._db)
        return user_obj

    def create_staffuser(self, email, password=None):    
        user = self.create_user(
            email,
            password=password,
            is_staff=True
        )
        return user

    def create_superuser(self, email, password=None):    
        user = self.create_user(
            email,
            password=password,
            is_staff=True,
            is_admin=True
        )
        return user

class User(AbstractBaseUser):    
    email = models.CharField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255, blank=False, null=False)
    last_name = models.CharField(max_length=255, blank=False, null=False)
    active = models.BooleanField(default=False)
    staff = models.BooleanField(default=False)
    admin = models.BooleanField(default=False)
    age = models.CharField(max_length=255, blank=False, null=False)
    address = models.CharField(max_length=255, blank=False, null=False)

    objects = UserManager()
    USERNAME_FIELD = 'email' # Email as Username
    REQUIRED_FIELDS = []

    def __str__(self):    
        return self.email

設置.py

DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'account.apps.AccountConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.postgres',
    'wagtail.contrib.forms',
    'wagtail.contrib.redirects',
    'wagtail.embeds',
    'wagtail.sites',
    'wagtail.users',
    'wagtail.snippets',
    'wagtail.documents',
    'wagtail.images',
    'wagtail.search',
    'wagtail.admin',
    'wagtail.core',
    'modelcluster',
    'taggit',
]

AUTH_USER_MODEL = 'account.User'

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
    'wagtail.core.middleware.SiteMiddleware',
    'wagtail.contrib.redirects.middleware.RedirectMiddleware',
]

ROOT_URLCONF = 'myproject.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'myproject.wsgi.application'


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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'Databasename',
        'USER': 'Username',
        'PASSWORD': 'Password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


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

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/Chicago'

USE_I18N = True

USE_L10N = True

USE_TZ = True


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

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

LOGIN_REDIRECT_URL = 'dashboard'
LOGIN_URL = 'login'
LOGOUT_URL = 'logout'

WAGTAIL_SITE_NAME = 'Myproject'

帳戶/admin.py

from django.contrib import admin
from .models import Program
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin

from .forms import UserAdminCreationForm, UserAdminChangeForm
from .models import User


class UserAdmin(BaseUserAdmin):
    form = UserAdminChangeForm
    add_form = UserAdminCreationForm

    list_display = ('email', 'admin')
    list_filter = ('admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Permissions', {'fields': ('admin',)}),
    )

    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2')}
        ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()


admin.site.register(User, UserAdmin)
admin.site.register(Program, ProgramList)

# Remove Group Model from admin. We're not using it.
admin.site.unregister(Group)

帳戶/forms.py

from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .models import User

class UserAdminCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email',)

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserAdminCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class UserAdminChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = User
        fields = ('email', 'password', 'active', 'admin')

    def clean_password(self):        
        return self.initial["password"]

錯誤

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\base.py", line 332, in execute
    self.check()
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\base.py", line 364, in check
    include_deployment_checks=include_deployment_checks,
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\management\base.py", line 351, in _run_checks
    return checks.run_checks(**kwargs)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\checks\registry.py", line 73, in run_checks
    new_errors = check(app_configs=app_configs)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\checks\urls.py", line 13, in check_url_config
    return check_resolver(resolver)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\core\checks\urls.py", line 23, in check_resolver
    return check_method()
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\urls\resolvers.py", line 399, in check
    for pattern in self.url_patterns:
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\utils\functional.py", line 36, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\urls\resolvers.py", line 540, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\utils\functional.py", line 36, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\urls\resolvers.py", line 533, in urlconf_module
    return import_module(self.urlconf_name)
  File "C:\Users\nikes\Anaconda3\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "C:\Users\nikes\Desktop\Version-3\empoweru\empoweru\urls.py", line 18, in <module>
    from wagtail.admin import urls as wagtailadmin_urls
  File "C:\Users\nikes\Anaconda3\lib\site-packages\wagtail\admin\urls\__init__.py", line 11, in <module>
    from wagtail.admin.urls import password_reset as wagtailadmin_password_reset_urls
  File "C:\Users\nikes\Anaconda3\lib\site-packages\wagtail\admin\urls\password_reset.py", line 3, in <module>
    from wagtail.admin.views import account
  File "C:\Users\nikes\Anaconda3\lib\site-packages\wagtail\admin\views\account.py", line 14, in <module>
    from wagtail.users.forms import (
  File "C:\Users\nikes\Anaconda3\lib\site-packages\wagtail\users\forms.py", line 178, in <module>
    class UserCreationForm(UserForm):
  File "C:\Users\nikes\Anaconda3\lib\site-packages\django\forms\models.py", line 266, in __new__
    raise FieldError(message)
django.core.exceptions.FieldError: Unknown field(s) (groups) specified for User

您的自定義用戶模型僅從AbstractBaseUser繼承,但 Wagtail 要求自定義用戶模型必須至少從AbstractBaseUserPermissionsMixin繼承。

class User(AbstractBaseUser):
   ...

變成

class AbstractUser(AbstractBaseUser, PermissionsMixin):
   ...

這會將groups字段添加到錯誤抱怨沒有的User

https://docs.wagtail.org/en/stable/advanced_topics/customisation/custom_user_models.html#custom-user-forms-example

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM