Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #11639, #13618 -- Added get_prepopulated_fields method to Model…

…Admin and InlineModelAdmin to be able to handle prepopulated fields on a case-by-case basis. Thanks, leanmeandonothingmachine.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16069 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 6c17190bf8c6c23f21dd49b029106dd5cb41ae2e 1 parent 51cfd7a
@jezdez jezdez authored
View
12 django/contrib/admin/helpers.py
@@ -193,7 +193,8 @@ class InlineAdminFormSet(object):
"""
A wrapper around an inline formset for use in the admin system.
"""
- def __init__(self, inline, formset, fieldsets, readonly_fields=None, model_admin=None):
+ def __init__(self, inline, formset, fieldsets, prepopulated_fields=None,
+ readonly_fields=None, model_admin=None):
self.opts = inline
self.formset = formset
self.fieldsets = fieldsets
@@ -201,18 +202,21 @@ def __init__(self, inline, formset, fieldsets, readonly_fields=None, model_admin
if readonly_fields is None:
readonly_fields = ()
self.readonly_fields = readonly_fields
+ if prepopulated_fields is None:
+ prepopulated_fields = {}
+ self.prepopulated_fields = prepopulated_fields
def __iter__(self):
for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
yield InlineAdminForm(self.formset, form, self.fieldsets,
- self.opts.prepopulated_fields, original, self.readonly_fields,
+ self.prepopulated_fields, original, self.readonly_fields,
model_admin=self.opts)
for form in self.formset.extra_forms:
yield InlineAdminForm(self.formset, form, self.fieldsets,
- self.opts.prepopulated_fields, None, self.readonly_fields,
+ self.prepopulated_fields, None, self.readonly_fields,
model_admin=self.opts)
yield InlineAdminForm(self.formset, self.formset.empty_form,
- self.fieldsets, self.opts.prepopulated_fields, None,
+ self.fieldsets, self.prepopulated_fields, None,
self.readonly_fields, model_admin=self.opts)
def fields(self):
View
21 django/contrib/admin/options.py
@@ -189,8 +189,17 @@ def _declared_fieldsets(self):
declared_fieldsets = property(_declared_fieldsets)
def get_readonly_fields(self, request, obj=None):
+ """
+ Hook for specifying custom readonly fields.
+ """
return self.readonly_fields
+ def get_prepopulated_fields(self, request, obj=None):
+ """
+ Hook for specifying custom prepopulated fields.
+ """
+ return self.prepopulated_fields
+
def queryset(self, request):
"""
Returns a QuerySet of all model instances that can be edited by the
@@ -909,7 +918,8 @@ def add_view(self, request, form_url='', extra_context=None):
formsets.append(formset)
adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)),
- self.prepopulated_fields, self.get_readonly_fields(request),
+ self.get_prepopulated_fields(request),
+ self.get_readonly_fields(request),
model_admin=self)
media = self.media + adminForm.media
@@ -917,8 +927,9 @@ def add_view(self, request, form_url='', extra_context=None):
for inline, formset in zip(self.inline_instances, formsets):
fieldsets = list(inline.get_fieldsets(request))
readonly = list(inline.get_readonly_fields(request))
+ prepopulated = dict(inline.get_prepopulated_fields(request))
inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
- fieldsets, readonly, model_admin=self)
+ fieldsets, prepopulated, readonly, model_admin=self)
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
@@ -1000,7 +1011,8 @@ def change_view(self, request, object_id, extra_context=None):
formsets.append(formset)
adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj),
- self.prepopulated_fields, self.get_readonly_fields(request, obj),
+ self.get_prepopulated_fields(request, obj),
+ self.get_readonly_fields(request, obj),
model_admin=self)
media = self.media + adminForm.media
@@ -1008,8 +1020,9 @@ def change_view(self, request, object_id, extra_context=None):
for inline, formset in zip(self.inline_instances, formsets):
fieldsets = list(inline.get_fieldsets(request, obj))
readonly = list(inline.get_readonly_fields(request, obj))
+ prepopulated = dict(inline.get_prepopulated_fields(request, obj))
inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
- fieldsets, readonly, model_admin=self)
+ fieldsets, prepopulated, readonly, model_admin=self)
inline_admin_formsets.append(inline_admin_formset)
media = media + inline_admin_formset.media
View
9 docs/ref/contrib/admin/index.txt
@@ -839,6 +839,15 @@ templates used by the :class:`ModelAdmin` views:
a ``list`` or ``tuple`` of field names that will be displayed as read-only,
as described above in the :attr:`ModelAdmin.readonly_fields` section.
+.. method:: ModelAdmin.get_prepopulated_fields(self, request, obj=None)
+
+ .. versionadded:: 1.4
+
+ The ``get_prepopulated_fields`` method is given the ``HttpRequest`` and the
+ ``obj`` being edited (or ``None`` on an add form) and is expected to return
+ a ``dictionary``, as described above in the :attr:`ModelAdmin.prepopulated_fields`
+ section.
+
.. method:: ModelAdmin.get_urls(self)
The ``get_urls`` method on a ``ModelAdmin`` returns the URLs to be used for
View
9 tests/regressiontests/admin_views/fixtures/admin-views-users.xml
@@ -88,6 +88,9 @@
<field type="DateTimeField" name="date">2009-03-18 11:54:58</field>
<field to="admin_views.section" name="section" rel="ManyToOneRel">1</field>
</object>
-
-
-</django-objects>
+ <object pk="1" model="admin_views.prepopulatedpost">
+ <field type="TextField" name="title">A Long Title</field>
+ <field type="BooleanField" name="published">True</field>
+ <field type="SlugField" name="slug">a-long-title</field>
+ </object>
+</django-objects>
View
46 tests/regressiontests/admin_views/models.py
@@ -529,6 +529,51 @@ class LinkInline(admin.TabularInline):
readonly_fields = ("posted",)
+class PrePopulatedPost(models.Model):
+ title = models.CharField(max_length=100)
+ published = models.BooleanField()
+ slug = models.SlugField()
+
+class PrePopulatedSubPost(models.Model):
+ post = models.ForeignKey(PrePopulatedPost)
+ subtitle = models.CharField(max_length=100)
+ subslug = models.SlugField()
+
+class SubPostInline(admin.TabularInline):
+ model = PrePopulatedSubPost
+
+ prepopulated_fields = {
+ 'subslug' : ('subtitle',)
+ }
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj and obj.published:
+ return ('subslug',)
+ return self.readonly_fields
+
+ def get_prepopulated_fields(self, request, obj=None):
+ if obj and obj.published:
+ return {}
+ return self.prepopulated_fields
+
+class PrePopulatedPostAdmin(admin.ModelAdmin):
+ list_display = ['title', 'slug']
+ prepopulated_fields = {
+ 'slug' : ('title',)
+ }
+
+ inlines = [SubPostInline]
+
+ def get_readonly_fields(self, request, obj=None):
+ if obj and obj.published:
+ return ('slug',)
+ return self.readonly_fields
+
+ def get_prepopulated_fields(self, request, obj=None):
+ if obj and obj.published:
+ return {}
+ return self.prepopulated_fields
+
class Post(models.Model):
title = models.CharField(max_length=100, help_text="Some help text for the title (with unicode ŠĐĆŽćžšđ)")
content = models.TextField(help_text="Some help text for the content (with unicode ŠĐĆŽćžšđ)")
@@ -818,3 +863,4 @@ class OtherStoryAdmin(admin.ModelAdmin):
admin.site.register(Album, AlbumAdmin)
admin.site.register(Question)
admin.site.register(Answer)
+admin.site.register(PrePopulatedPost, PrePopulatedPostAdmin)
View
24 tests/regressiontests/admin_views/tests.py
@@ -2579,6 +2579,30 @@ def testJsi18n(self):
self.assertEqual(get_max_age(response), None)
+class PrePopulatedTest(TestCase):
+ fixtures = ['admin-views-users.xml']
+
+ def setUp(self):
+ self.client.login(username='super', password='secret')
+
+ def tearDown(self):
+ self.client.logout()
+
+ def test_prepopulated_on(self):
+ response = self.client.get('/test_admin/admin/admin_views/prepopulatedpost/add/')
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, "id: '#id_slug',")
+ self.assertContains(response, "field['dependency_ids'].push('#id_title');")
+ self.assertContains(response, "id: '#id_prepopulatedsubpost_set-0-subslug',")
+
+ def test_prepopulated_off(self):
+ response = self.client.get('/test_admin/admin/admin_views/prepopulatedpost/1/')
+ self.assertEqual(response.status_code, 200)
+ self.assertContains(response, "A Long Title")
+ self.assertNotContains(response, "id: '#id_slug'")
+ self.assertNotContains(response, "field['dependency_ids'].push('#id_title');")
+ self.assertNotContains(response, "id: '#id_prepopulatedsubpost_set-0-subslug',")
+
class ReadonlyTest(TestCase):
fixtures = ['admin-views-users.xml']
Please sign in to comment.
Something went wrong with that request. Please try again.