I agree with Marc that so many ways to do things isn't ideal, but I don't
see a different simple way to accommodate Peter's use case, so +0 to adding
get_exclude().
On Saturday, June 6, 2015 at 11:44:53 AM UTC-4, Peter J. Farrell wrote:
>
> In our case, we need to dynamically include additional "exclude" fields in
> our VersionableAdmin and not override the selections the developer has set
> in their subclass. There are two options to accomplished this:
>
> 1) Override get_form() which is messy because you can't just call super
> here and modify things. This is a lot of code duplication to just get at
> the exclude
>
> def get_form(self, request, obj=None, **kwargs):
> """
> Returns a Form class for use in the admin add view. This is used by
> add_view and change_view.
> """
> if 'fields' in kwargs:
> fields = kwargs.pop('fields')
> else:
> fields = flatten_fieldsets(self.get_fieldsets(request, obj))
> if self.exclude is None:
> exclude = []
> else:
> exclude = list(self.exclude)
> exclude.extend(self.get_readonly_fields(request, obj))
> if self.exclude is None and hasattr(self.form, '_meta') and
> self.form._meta.exclude:
> # Take the custom ModelForm's Meta.exclude into account only if the
> # ModelAdmin doesn't define its own.
> exclude.extend(self.form._meta.exclude)
> # if exclude is an empty list we pass None to be consistent with the
> # default on modelform_factory
> exclude = exclude or None
> defaults = {
> "form": self.form,
> "fields": fields,
> "exclude": exclude,
> "formfield_callback": partial(self.formfield_for_dbfield,
> request=request),
> }
> defaults.update(kwargs)
>
> if defaults['fields'] is None and not
> modelform_defines_fields(defaults['form']):
> defaults['fields'] = forms.ALL_FIELDS
>
> try:
> return modelform_factory(self.model, **defaults)
> except FieldError as e:
> raise FieldError('%s. Check fields/fieldsets/exclude attributes of
> class %s.'
> % (e, self.__class__.__name__))
>
>
> 2) Build your own descriptor for exclude:
>
> @property
> def exclude(self):
> """
> Custom descriptor for exclude since there is no get_exclude method to be
> overridden
> """
> exclude = self.VERSIONED_EXCLUDE
>
> if super(VersionedAdmin, self).exclude is not None:
> # Force cast to list as super exclude could return a tuple
> exclude = list(super(VersionedAdmin, self).exclude) + exclude
>
> return exclude
>
>
> But then this trips the _check_exclude check in ModelAdminChecks for not
> being a list or tuple. So you have to subclass that:
>
> class VersionedAdminChecks(ModelAdminChecks):
> def _check_exclude(self, cls, model):
> """
> Required to suppress error about exclude not being a tuple since we
> are using @property to dynamically change it
> """
> return []
>
>
> All of this is a lot of effort just to get at dynamic exclude where
> get_exclude() fits the current pattern used in the admin in the current
> code base.
>
>
--
You received this message because you are subscribed to the Google Groups
"Django developers (Contributions to Django itself)" 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].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/6b36c786-deb1-4878-a94e-1f6487c95c18%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.