我正在尝试覆盖django ModelAdmin中的get_readonly_fields()
方法。如果存在某种情况,我想将几乎所有字段都返回为readonly_fields。这是看起来的样子:
from django.contrib import admin
from cms.admin.placeholderadmin import PlaceholderAdminMixin
from .models import (Story, StoryCategory, AVAILABLE_STORY, GLOBAL_STORY)
RESTRICTED_PUB_FIELDS = ('pub_date',)
RESTRICTED_FIELDS = (
'global_status',
'title',
'byline',
'byline_headshot',
'featured_image',
'use_featured_image_on_detail_page',
'outside_article_box',
'has_detail_page',
'landing_page_link',
'link_text',
'global_categories',
'initiatives_tags',
'stat_text_before',
'stat_number',
'stat_text_after',
'offices',
'rural_liscs',
)
class StoryAdmin(PlaceholderAdminMixin, admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
if obj and obj.global_status == AVAILABLE_STORY:
fields = self.readonly_fields + \
RESTRICTED_PUB_FIELDS + RESTRICTED_FIELDS
return fields
return self.readonly_fields
def change_view(self, request, object_id, extra_context=None):
if '_saveasnew' in request.POST:
if request.POST['global_status'] == AVAILABLE_STORY:
request.POST['global_status'] = GLOBAL_STORY
return super(StoryAdmin, self).change_view(
request, object_id, extra_context=extra_context
)
fieldsets = (
('Publishing Information', {
'fields': (
'status', RESTRICTED_PUB_FIELDS, 'expire_date', 'slug'
)
}),
(None, {'fields': (
RESTRICTED_FIELDS,
'excerpt',
'local_categories',
'is_featured',
)}),
)
[...]
admin.site.register(Story, StoryAdmin)
但是当get_readonly_fields()
中的条件为真时,会引发KeyError - 而不是Story
对象而是StoryForm
。我知道Django为我动态创建了一个ModelForm,所以我假设我在某些时候错误地传递了一些东西,但是我看不到它在哪里。我试着几乎逐字逐句地回答这个问题:https://stackoverflow.com/a/11601613/4846824
这是完整的堆栈跟踪:
Environment:
Request Method: GET
Request URL: http://localhost:8000/communitycenter/stories/story/369/
Django Version: 1.7.8
Python Version: 2.7.10
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
'django.contrib.messages',
'django.contrib.redirects',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.sitemaps',
'djangocms_admin_style',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.staticfiles',
'djangocms_text_ckeditor',
'cms',
'djangocms_snippet',
'filer',
'menus',
'sekizai',
'djangocms_link',
'clear_cache',
'compressor',
'constance',
'constance.backends.database',
'adminsortable',
'django_extensions',
'easy_thumbnails',
'gunicorn',
'haystack',
'memcache_status',
'mptt',
'simplejson',
'tinymce',
'treebeard',
'twython',
'apps.common',
'apps.charter',
'apps.submenu',
'apps.offices',
'apps.events',
'apps.microsites',
'apps.resources',
'apps.search',
'apps.stories',
'apps.plugins',
'apps.twitter',
'apps.charter_calculator')
Installed Middleware:
('django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
'django.middleware.locale.LocaleMiddleware',
'cms.middleware.page.CurrentPageMiddleware',
'cms.middleware.user.CurrentUserMiddleware',
'cms.middleware.toolbar.ToolbarMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware')
Traceback:
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
583. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
105. response = view_func(request, *args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
52. response = view_func(request, *args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
206. return view(request, *args, **kwargs)
File "/Users/kedmundson/DEV/lisc/source/apps/stories/admin.py" in change_view
46. request, object_id, extra_context=extra_context
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/contrib/admin/options.py" in change_view
1456. return self.changeform_view(request, object_id, form_url, extra_context)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
29. return bound_func(*args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
105. response = view_func(request, *args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
25. return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/db/transaction.py" in inner
394. return func(*args, **kwargs)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/contrib/admin/options.py" in changeform_view
1427. model_admin=self)
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/contrib/admin/helpers.py" in __init__
36. } for field_name, dependencies in prepopulated_fields.items()]
File "/Users/kedmundson/.virtualenvs/lisc/lib/python2.7/site-packages/django/forms/forms.py" in __getitem__
147. "Key %r not found in '%s'" % (name, self.__class__.__name__))
Exception Type: KeyError at /communitycenter/stories/story/369/
Exception Value: u"Key 'title' not found in 'StoryForm'"
答案 0 :(得分:1)
啊哈。问题是我的a
值:
prepopulated_fields
看起来让prepopulated_fields = {'slug': ('title',)}
只读,使其无法预填充title
字段。但这对我来说没关系,因为用户无论如何都必须更改slug,所以我添加了slug
的覆盖,它与get_prepopulated_fields()
中的条件检查相同:
get_readonly_fields()