mirror of https://github.com/django/django.git
Fixed #10208: `ModelAdmin` now respects the `exclude` and `field` atributes of custom `ModelForm`s. Thanks, Alex Gaynor.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10619 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
71233bcdf3
commit
6c15b5db60
|
@ -336,10 +336,12 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
exclude = []
|
exclude = []
|
||||||
else:
|
else:
|
||||||
exclude = list(self.exclude)
|
exclude = list(self.exclude)
|
||||||
|
# if exclude is an empty list we pass None to be consistant with the
|
||||||
|
# default on modelform_factory
|
||||||
defaults = {
|
defaults = {
|
||||||
"form": self.form,
|
"form": self.form,
|
||||||
"fields": fields,
|
"fields": fields,
|
||||||
"exclude": exclude + kwargs.get("exclude", []),
|
"exclude": (exclude + kwargs.get("exclude", [])) or None,
|
||||||
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
|
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
|
||||||
}
|
}
|
||||||
defaults.update(kwargs)
|
defaults.update(kwargs)
|
||||||
|
@ -1138,12 +1140,14 @@ class InlineModelAdmin(BaseModelAdmin):
|
||||||
exclude = []
|
exclude = []
|
||||||
else:
|
else:
|
||||||
exclude = list(self.exclude)
|
exclude = list(self.exclude)
|
||||||
|
# if exclude is an empty list we use None, since that's the actual
|
||||||
|
# default
|
||||||
defaults = {
|
defaults = {
|
||||||
"form": self.form,
|
"form": self.form,
|
||||||
"formset": self.formset,
|
"formset": self.formset,
|
||||||
"fk_name": self.fk_name,
|
"fk_name": self.fk_name,
|
||||||
"fields": fields,
|
"fields": fields,
|
||||||
"exclude": exclude + kwargs.get("exclude", []),
|
"exclude": (exclude + kwargs.get("exclude", [])) or None,
|
||||||
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
|
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
|
||||||
"extra": self.extra,
|
"extra": self.extra,
|
||||||
"max_num": self.max_num,
|
"max_num": self.max_num,
|
||||||
|
|
|
@ -344,16 +344,34 @@ class ModelForm(BaseModelForm):
|
||||||
|
|
||||||
def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
||||||
formfield_callback=lambda f: f.formfield()):
|
formfield_callback=lambda f: f.formfield()):
|
||||||
# HACK: we should be able to construct a ModelForm without creating
|
# Create the inner Meta class. FIXME: ideally, we should be able to
|
||||||
# and passing in a temporary inner class
|
# construct a ModelForm without creating and passing in a temporary
|
||||||
class Meta:
|
# inner class.
|
||||||
pass
|
|
||||||
setattr(Meta, 'model', model)
|
# Build up a list of attributes that the Meta object will have.
|
||||||
setattr(Meta, 'fields', fields)
|
attrs = {'model': model}
|
||||||
setattr(Meta, 'exclude', exclude)
|
if fields is not None:
|
||||||
|
attrs['fields'] = fields
|
||||||
|
if exclude is not None:
|
||||||
|
attrs['exclude'] = exclude
|
||||||
|
|
||||||
|
# If parent form class already has an inner Meta, the Meta we're
|
||||||
|
# creating needs to inherit from the parent's inner meta.
|
||||||
|
parent = (object,)
|
||||||
|
if hasattr(form, 'Meta'):
|
||||||
|
parent = (form.Meta, object)
|
||||||
|
Meta = type('Meta', parent, attrs)
|
||||||
|
|
||||||
|
# Give this new form class a reasonable name.
|
||||||
class_name = model.__name__ + 'Form'
|
class_name = model.__name__ + 'Form'
|
||||||
return ModelFormMetaclass(class_name, (form,), {'Meta': Meta,
|
|
||||||
'formfield_callback': formfield_callback})
|
# Class attributes for the new form class.
|
||||||
|
form_class_attrs = {
|
||||||
|
'Meta': Meta,
|
||||||
|
'formfield_callback': formfield_callback
|
||||||
|
}
|
||||||
|
|
||||||
|
return ModelFormMetaclass(class_name, (form,), form_class_attrs)
|
||||||
|
|
||||||
|
|
||||||
# ModelFormSets ##############################################################
|
# ModelFormSets ##############################################################
|
||||||
|
@ -617,13 +635,6 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
|
||||||
# enforce a max_num=1 when the foreign key to the parent model is unique.
|
# enforce a max_num=1 when the foreign key to the parent model is unique.
|
||||||
if fk.unique:
|
if fk.unique:
|
||||||
max_num = 1
|
max_num = 1
|
||||||
if fields is not None:
|
|
||||||
fields = list(fields)
|
|
||||||
fields.append(fk.name)
|
|
||||||
else:
|
|
||||||
# get all the fields for this model that will be generated.
|
|
||||||
fields = fields_for_model(model, fields, exclude, formfield_callback).keys()
|
|
||||||
fields.append(fk.name)
|
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'form': form,
|
'form': form,
|
||||||
'formfield_callback': formfield_callback,
|
'formfield_callback': formfield_callback,
|
||||||
|
|
|
@ -37,7 +37,7 @@ class ValidationTestInlineModel(models.Model):
|
||||||
|
|
||||||
__test__ = {'API_TESTS': """
|
__test__ = {'API_TESTS': """
|
||||||
|
|
||||||
>>> from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL
|
>>> from django.contrib.admin.options import ModelAdmin, TabularInline, HORIZONTAL, VERTICAL
|
||||||
>>> from django.contrib.admin.sites import AdminSite
|
>>> from django.contrib.admin.sites import AdminSite
|
||||||
|
|
||||||
None of the following tests really depend on the content of the request, so
|
None of the following tests really depend on the content of the request, so
|
||||||
|
@ -262,6 +262,46 @@ blank=True for the model field. Finally, the widget should have the
|
||||||
>>> list(cmafa.base_fields['transport'].widget.choices)
|
>>> list(cmafa.base_fields['transport'].widget.choices)
|
||||||
[('', u'None'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')]
|
[('', u'None'), (1, 'Plane'), (2, 'Train'), (3, 'Bus')]
|
||||||
|
|
||||||
|
>>> class AdminConcertForm(forms.ModelForm):
|
||||||
|
... class Meta:
|
||||||
|
... model = Concert
|
||||||
|
... exclude = ('transport',)
|
||||||
|
|
||||||
|
>>> class ConcertAdmin(ModelAdmin):
|
||||||
|
... form = AdminConcertForm
|
||||||
|
|
||||||
|
>>> ma = ConcertAdmin(Concert, site)
|
||||||
|
>>> ma.get_form(request).base_fields.keys()
|
||||||
|
['main_band', 'opening_band', 'day']
|
||||||
|
|
||||||
|
>>> class AdminConcertForm(forms.ModelForm):
|
||||||
|
... extra = forms.CharField()
|
||||||
|
... class Meta:
|
||||||
|
... model = Concert
|
||||||
|
... fields = ['extra', 'transport']
|
||||||
|
|
||||||
|
>>> class ConcertAdmin(ModelAdmin):
|
||||||
|
... form = AdminConcertForm
|
||||||
|
|
||||||
|
>>> ma = ConcertAdmin(Concert, site)
|
||||||
|
>>> ma.get_form(request).base_fields.keys()
|
||||||
|
['extra', 'transport']
|
||||||
|
|
||||||
|
>>> class ConcertInline(TabularInline):
|
||||||
|
... form = AdminConcertForm
|
||||||
|
... model = Concert
|
||||||
|
... fk_name = 'main_band'
|
||||||
|
|
||||||
|
>>> class BandAdmin(ModelAdmin):
|
||||||
|
... inlines = [
|
||||||
|
... ConcertInline
|
||||||
|
... ]
|
||||||
|
|
||||||
|
>>> ma = BandAdmin(Band, site)
|
||||||
|
>>> list(ma.get_formsets(request))[0]().forms[0].fields.keys()
|
||||||
|
['extra', 'transport', 'id', 'DELETE', 'main_band']
|
||||||
|
|
||||||
|
|
||||||
>>> band.delete()
|
>>> band.delete()
|
||||||
|
|
||||||
# ModelAdmin Option Validation ################################################
|
# ModelAdmin Option Validation ################################################
|
||||||
|
|
Loading…
Reference in New Issue