#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.

Reply via email to