当我尝试创建 abstractUser 模型类时,我在输入AUTH_USER_MODEL = 'blog.User
settings.py 后收到此错误消息,我遵循 Wagtail 自定义用户模型示例The Link to the site。
我正在使用 Django 1.11.3 和 wagtail 2.0,python 3.5.4
Sitename = mysite
Appname = Blog
Model = Models.py
用户类
堆栈跟踪
(wagtail-9p7xWA1-) 0-10:22-/mnt/c/dev/wagtail/mysite (master) $ ./manage.py runserver
.wrapper 在 0x7fc502ce8840 > Traceback 启动的线程中未处理的异常(最近一次调用最后一次):文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/ utils/autoreload.py”,第 227 行,在包装器 fn(*args, **kwargs) 文件中“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/ django/core/management/commands/runserver.py”,第 117 行,inner_run autoreload.raise_last_exception() 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site- packages/django/utils/autoreload.py”,第 250 行,在 raise_last_exception 六.reraise(*_exception) 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-包/django/utils/six.py”,第 685 行,在 reraise raise value.with_traceback(tb) 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/utils/autoreload.py”,第 227 行,在包装器 fn(*args, **kwargs) 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/init .py”,第 27 行,在 setup apps.populate(settings.INSTALLED_APPS) 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/apps /registry.py”,第 108 行,在填充 app_config.import_models() 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/apps/config .py”,第 202 行,在 import_models self.models_module = import_module(models_module_name) 文件“ /home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/importlib/init.py”,第 126 行,在 import_module 中 return _bootstrap._gcd_import(name[level:], package, level) 文件“”,第 986 行,在 _gcd_import 文件中“”,第 969 行,在 _find_and_load 文件中“”,第 958 行,在_find_and_load_unlocked 文件“”,第 673 行,在 _load_unlocked
文件“”,第 665 行,在 exec_module 中 文件“”,第 222 行,在 _call_with_frames_removed 文件“/mnt/c/dev/wagtail/mysite/home/models.py”,第 5 行,在 from wagtail.admin.edit_handlers import FieldPanel文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/wagtail/admin/edit_handlers.py”,第 23 行,从 .forms 导入(#NOQA 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/wagtail/admin/forms.py”,第 6 行,来自 django.contrib.auth.forms 导入AuthenticationForm,PasswordResetForm 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/contrib/auth/forms.py”,第 22 行,在 UserModel = get_user_model () 文件 ”/home/用户名/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/django/contrib/auth/init .py”,第 193 行,在 get_user_model 返回 django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False) 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site- packages/django/apps/registry.py”,第 203 行,在 get_model app_config.import_models() 文件“/home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/site-packages/ django/apps/config.py”,第 202 行,在 import_models self.models_module = import_module(models_module_name) 文件“ /home/Username/.local/share/virtualenvs/wagtail-9p7xWA1-/lib/python3.5/importlib/init.py”,第 126 行,在 import_module 返回 _bootstrap._gcd_import(name[level:], package, level) 文件“/mnt/c/dev/wagtail/mysite/blog/models.py”,第 17 行,来自 wagtail .admin.edit_handlers 导入 FieldPanel、MultiFieldPanel、\ImportError:无法导入名称“FieldPanel”
如果我这样做,一些代码
博客/Models.py
from django import forms
from django.db import models
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase
from wagtail.core.models import Page, Orderable
from wagtail.snippets.models import register_snippet
from wagtail.core.fields import RichTextField, StreamField
from wagtail.core.blocks import StructBlock, TextBlock, StreamBlock, \
EmailBlock, CharBlock, RichTextBlock
from wagtail.images.blocks import ImageChooserBlock
from wagtail.embeds.blocks import EmbedBlock
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel, \
InlinePanel, StreamFieldPanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.search import index
richtext_features = [
'h1', 'h2', 'h3', 'hr',
'bold', 'italic', 'link',
'ol', 'ul', 'embed', 'image',
]
class BlogIndexPage(Page):
intro = RichTextField(blank=True)
def get_context(self, request):
# Update context to include only published posts, ordered by reverse-chron
context = super().get_context(request)
blogpages = self.get_children().live().order_by('-first_published_at')
context['blogpages'] = blogpages
return context
class BlogPageTag(TaggedItemBase):
content_object = ParentalKey(
'BlogPage',
related_name='tagged_items',
on_delete=models.CASCADE
)
class BlogTagIndexPage(Page):
def get_context(self, request):
tag = request.GET.get('tag')
blogpages = BlogPage.objects.filter(tags__name=tag)
context = super().get_context(request)
context['blogpages'] = blogpages
return context
class BlogPage(Page):
date = models.DateField("Post date")
intro = models.CharField(max_length=250)
body = RichTextField(blank=True)
tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
categories = ParentalManyToManyField('blog.BlogCategory', blank=True)
feed_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
def main_image(self):
gallery_item = self.gallery_images.first()
if gallery_item:
return gallery_item.image
else:
return None
search_fields = Page.search_fields + [
index.SearchField('intro'),
index.SearchField('body'),
index.FilterField('date'),
]
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('date'),
FieldPanel('tags'),
FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
], heading="Blog information"),
FieldPanel('intro'),
FieldPanel('body', classname="full"),
InlinePanel('gallery_images', label="Gallery Images"),
]
promote_panels = [
MultiFieldPanel(Page.promote_panels, 'Common page Config'),
ImageChooserPanel('feed_image'),
]
class BlogPageRelatedLink(Orderable):
page = ParentalKey(BlogPage, related_name='related_links')
name = models.CharField(max_length=255)
url = models.URLField()
panels = [
FieldPanel('name'),
FieldPanel('url'),
]
class BlogPageGalleryImage(Orderable):
page = ParentalKey(
BlogPage,
on_delete=models.CASCADE,
related_name='gallery_images'
)
image = models.ForeignKey(
'wagtailimages.Image',
on_delete=models.CASCADE,
related_name='+'
)
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption')
]
class PersonBlock(StructBlock):
name = CharBlock(icon="user")
image = ImageChooserBlock(required=False, icon="image")
email = EmailBlock(icon="mail")
class Meta:
template = 'blocks/person.html'
class TwoColumnBlock(StructBlock):
left_column = PersonBlock(icon='arrow-right', label='Left column content')
right_column = PersonBlock(icon='arrow-right', label='Right column content')
class Meta:
template = 'blocks/person.html'
icon = 'user'
label = 'Two Columns'
class StoryBlock(StreamBlock):
title = TextBlock(classname="full title")
text = RichTextBlock(features=richtext_features)
class Meta:
icon = 'bold'
template = 'blocks/column.html'
class TwoStoryBlock(StructBlock):
left_column = StoryBlock(icon='arrow-right', label='Left column content')
right_column = StoryBlock(icon='arrow-right', label='Right column content')
class Meta:
template = 'blocks/two_column_block.html'
icon = 'bold'
class BackgroundBlock(StructBlock):
background = ImageChooserBlock(icon="image")
streamblock = StreamBlock(
[
('title', CharBlock(classname="full title")),
('person', PersonBlock()),
('twocolumnblock', TwoColumnBlock()),
('twostoryblock', TwoStoryBlock()),
('richtext', RichTextBlock(features=richtext_features)),
],
required=False
)
class Meta:
icon = 'cogs'
template = 'blocks/background.html'
class BackgroundNoButtonBlock(StructBlock):
background = ImageChooserBlock(icon="image")
streamblock = StreamBlock(
[
('title', CharBlock(classname="full title")),
('richtext', RichTextBlock(features=richtext_features)),
],
required=False
)
class Meta:
icon = 'cogs'
template = 'blocks/background_no_button.html'
class TextAndImageBlock (StreamBlock):
text = RichTextBlock(features=richtext_features)
image = ImageChooserBlock()
class Meta:
icon = 'bold'
template = 'blocks/column.html'
class TwoTextAndImageBlock(StructBlock):
left_column = TextAndImageBlock(icon='arrow-right', label='Left column content')
right_column = TextAndImageBlock(icon='arrow-right', label='Right column content')
class Meta:
template = 'blocks/two_column_block.html'
icon = 'bold'
class LandingPage(Page):
body = StreamField(
[
('heading', CharBlock(classname="full title")),
('paragraph', RichTextBlock()),
('backgroundnobutton', BackgroundNoButtonBlock()),
('background', BackgroundBlock(max_num=10, block_counts={'video': {'max_num': 2}})),
('embedded_video', EmbedBlock(icon="media")),
('twostoryblock', TwoStoryBlock(icon="bold")),
('two_column_block', TwoColumnBlock(icon="view")),
('textandimage', TwoTextAndImageBlock()),
],
null=True,
blank=True
)
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
@register_snippet
class BlogCategory(models.Model):
name = models.CharField(max_length=255)
icon = models.ForeignKey(
'wagtailimages.Image', null=True, blank=True,
on_delete=models.SET_NULL, related_name='+'
)
panels = [
FieldPanel('name'),
ImageChooserPanel('icon'),
]
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'blog categories'
设置/base.py
import os
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = os.path.dirname(PROJECT_DIR)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# Application definition
INSTALLED_APPS = [
'home',
'search',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
'users',
'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',
]
MIDDLEWARE = [
'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',
'django.middleware.security.SecurityMiddleware',
'wagtail.core.middleware.SiteMiddleware',
'wagtail.contrib.redirects.middleware.RedirectMiddleware',
]
ROOT_URLCONF = 'mysite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(PROJECT_DIR, 'templates'),
],
'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 = 'mysite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
WAGTAILGRIDDER_CLEAR_CACHE = False
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
AUTH_USER_MODEL = 'users.User'
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 = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATICFILES_DIRS = [
os.path.join(PROJECT_DIR, 'static'),
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_URL = '/static/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
# Wagtail settings
WAGTAIL_SITE_NAME = "mysite"
# Base URL to use when referring to full URLs within the Wagtail admin backend -
# e.g. in notification emails. Don't include '/admin' or a trailing slash
BASE_URL = 'http://example.com'
*用户/模型.py *
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass