#24187: admin.ModelAdmin base-class Cross referencing fields
---------------------------------+------------------------
Reporter: chazmead | Owner: nobody
Type: Uncategorized | Status: new
Component: contrib.admin | Version: 1.7
Severity: Release blocker | Keywords: ModelAdmin
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+------------------------
Hello,
I have found a bug on the ModelAdmin, I will try my best to explain.
My Environment is as follows:
Vagrant / Debian VM
nginx webserver
uWSGI webserver
Django 1.7.3
Grappelli admin panel
Basically I have a website, which has 2 types of articles Global and Local
articles, each model inherit from a base (abstract) model:
{{{
class ArticleBase(models.Model):
title = models.CharField(max_length=100, null=False,
help_text="Character limit: 100")
body = club_fields.WysiwygField(blank=True)
etc...
class Meta(object):
abstract = True
class Article(ArticleBase):
# Can't be set in base as is unique in Global but not unique by itself
in localised article
slug = models.SlugField(max_length=100, unique=True)
class Meta(object):
index_together = [
["slug", "status"],
]
ordering = ("-creation_date",)
class LocalisedArticle(ArticleBase):
# Can't be set in base as is unique in Global but not unique by itself
in localised article
slug = models.SlugField(max_length=100)
locale = models.CharField(max_length=10, null=False,
choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)
class Meta(object):
unique_together = (
("slug", "locale")
)
index_together = [
["slug", "status", "locale"],
]
ordering = ("-pub_date",)
}}}
And I have setup the admin classes to follow a similar suit, where each
article admin inherits from a baseclass which sets up fieldsets etc..
{{{
class ArticleAdmin(ImageCroppingMixin,admin.ModelAdmin):
ordering = ("-pub_date",)
list_display = ["title", "pub_date", "status", "update_date"]
prepopulated_fields = {"slug": ("title", ), }
exclude = ("overview_image", "hero_image")
fieldsets = [
["Meta", {
"fields": ("title", "heading_intro", "heading_sub", "slug",
"status", "pub_date", "meta_description", "social_description",
"article_type", "category", "download")
}],
["Content", {
"fields": ("body", "image", "overview_crop",
"overview_alignment", "hero_crop", "video_id", "discussion_question",
"disable_comments")
}],
]
class GlobalArticleAdmin(ArticleAdmin):
inlines = [
ArticleInlineImageAdmin,
ArticleCarouselInlineAdmin
]
class LocalisedArticleAdmin(ArticleAdmin):
list_filter = ("locale", "status")
inlines = [
LocalisedArticleInlineAdmin,
LocalisedArticleCarouselInlineAdmin,
ArticleCommentInlineAdmin,
]
def get_list_display(self, request):
list_display = super(LocalisedArticleAdmin,
self).get_list_display(request)
return list_display + ['locale']
def get_fieldsets(self, request, obj=None):
fieldsets = super(LocalisedArticleAdmin,
self).get_fieldsets(request, obj)
for i, fieldset in enumerate(fieldsets):
if fieldset[0] == 'Meta':
if 'locale' not in fieldset[1]['fields']:
fieldsets[i][1]['fields'] += ('locale',)
break
return fieldsets
def get_form(self, request, obj=None, **kwargs):
form = super(LocalisedArticleAdmin, self).get_form(request, obj,
**kwargs)
editable_locales = self.get_editable_locales(request)
locale_choices = []
for lang in settings.LANGUAGES:
if lang[0] in editable_locales:
locale_choices.append(lang)
form.base_fields['locale'].choices = locale_choices
return form
admin.site.register(Article, GlobalArticleAdmin)
admin.site.register(LocalisedArticle, LocalisedArticleAdmin)
}}}
In the localised article admin class, I have overloaded certain methods to
include the Locale Field in the forms, with appropriate editable locales
based on custom model permissions (I haven't included the entire class as
they are quite long, and I don't think the most part is necessary)
== The Bug
Now, the bug is that, I can view the global article admin page no problems
if I go to that admin page first, but as soon as I goto the localised
article admin and save a localised article model, and go back to the
global article admin page I get the following error:
{{{
Request Method: GET
Request URL: http://localhost:8000/admin/my_app/article/1/
Django Version: 1.7.3
Python Version: 2.7.3
Installed Applications:
(u'django.contrib.auth',
u'django.contrib.contenttypes',
u'django.contrib.sessions',
u'django.contrib.messages',
u'django.contrib.staticfiles',
u'compressor',
u'imagekit',
u'haystack',
u'my_app',
u'grappelli.dashboard',
u'grappelli',
u'django.contrib.admin',
u'django_user_agents',
u'easy_thumbnails',
u'image_cropping')
Installed Middleware:
(u'django.contrib.sessions.middleware.SessionMiddleware',
u'django.middleware.locale.LocaleMiddleware',
u'django.middleware.common.CommonMiddleware',
u'django.middleware.csrf.CsrfViewMiddleware',
u'django.contrib.auth.middleware.AuthenticationMiddleware',
u'django.contrib.messages.middleware.MessageMiddleware',
u'django.middleware.clickjacking.XFrameOptionsMiddleware',
u'django_user_agents.middleware.UserAgentMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py"
in get_response
111. response = wrapped_callback(request,
*callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-
packages/django/contrib/admin/options.py" in wrapper
583. return self.admin_site.admin_view(view)(*args,
**kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py"
in _wrapped_view
105. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-
packages/django/views/decorators/cache.py" in _wrapped_view_func
52. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-
packages/django/contrib/admin/sites.py" in inner
206. return view(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-
packages/django/contrib/admin/options.py" in change_view
1456. return self.changeform_view(request, object_id, form_url,
extra_context)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py"
in _wrapper
29. return bound_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py"
in _wrapped_view
105. response = view_func(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py"
in bound_func
25. return func.__get__(self, type(self))(*args2,
**kwargs2)
File "/usr/local/lib/python2.7/dist-packages/django/db/transaction.py" in
inner
394. return func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-
packages/django/contrib/admin/options.py" in changeform_view
1393. ModelForm = self.get_form(request, obj)
File "/usr/local/lib/python2.7/dist-
packages/django/contrib/admin/options.py" in get_form
670. % (e, self.__class__.__name__))
Exception Type: FieldError at /admin/my_app/article/1/
Exception Value: Unknown field(s) (locale) specified for Article. Check
fields/fieldsets/exclude attributes of class GlobalArticleAdmin.
}}}
Now, no where in the Article model, ArticleAdmin base class, or the
GlobalArticleAdmin class is the field 'locale' referenced, the ONLY place
this field is referenced is in the LocalisedArticle model and the
LocalArticleAdmin class overloaded form and field methods.. and as I say,
this only comes up after I save a Localiased article, if I reload the
uWSGI instance, I can access the GlobalArticleAdmin no problem.. and this
does not happen if I remove the ArticleAdmin base class, and duplicate the
code in both admin classes..
I have no idea why the GlobalArticleAdmin is trying to add a 'locale'
field to the admin page..
Please advise.
--
Ticket URL: <https://code.djangoproject.com/ticket/24187>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.bf0042b831ed46f9639bd45c41f5b91f%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.