Code

Ticket #19425: patch_ticket_19425_b.txt

File patch_ticket_19425_b.txt, 4.0 KB (added by areski, 11 months ago)
Line 
1diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
2index 7373837..e9324f6 100644
3--- a/django/contrib/admin/options.py
4+++ b/django/contrib/admin/options.py
5@@ -13,7 +13,7 @@ from django.contrib.admin.util import (unquote, flatten_fieldsets, get_deleted_o
6 from django.contrib.admin.templatetags.admin_static import static
7 from django.contrib import messages
8 from django.views.decorators.csrf import csrf_protect
9-from django.core.exceptions import PermissionDenied, ValidationError, FieldError
10+from django.core.exceptions import PermissionDenied, ValidationError, FieldError, ImproperlyConfigured
11 from django.core.paginator import Paginator
12 from django.core.urlresolvers import reverse
13 from django.db import models, transaction, router
14@@ -1467,6 +1467,14 @@ class InlineModelAdmin(BaseModelAdmin):
15             js.extend(['SelectBox.js', 'SelectFilter2.js'])
16         return forms.Media(js=[static('admin/js/%s' % url) for url in js])
17 
18+    def get_extra(self, request, obj=None, **kwargs):
19+        """Get the number of extra inline forms needed"""
20+        # extra = 3
21+        if not isinstance(self.extra, int):
22+            raise ImproperlyConfigured("'%s.extra' should be a integer."
23+                                       % self.__class__.__name__)
24+        return self.extra
25+
26     def get_formset(self, request, obj=None, **kwargs):
27         """Returns a BaseInlineFormSet class for use in admin add/change views."""
28         if self.declared_fieldsets:
29@@ -1493,7 +1501,7 @@ class InlineModelAdmin(BaseModelAdmin):
30             "fields": fields,
31             "exclude": exclude,
32             "formfield_callback": partial(self.formfield_for_dbfield, request=request),
33-            "extra": self.extra,
34+            "extra": self.get_extra(request, obj, *kwargs),
35             "max_num": self.max_num,
36             "can_delete": can_delete,
37         }
38diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
39index 8d65f96..06b5055 100644
40--- a/django/contrib/admin/validation.py
41+++ b/django/contrib/admin/validation.py
42@@ -199,11 +199,6 @@ def validate_inline(cls, parent, parent_model):
43 
44     fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
45 
46-    # extra = 3
47-    if not isinstance(cls.extra, int):
48-        raise ImproperlyConfigured("'%s.extra' should be a integer."
49-                % cls.__name__)
50-
51     # max_num = None
52     max_num = getattr(cls, 'max_num', None)
53     if max_num is not None and not isinstance(max_num, int):
54diff --git a/tests/admin_inlines/admin.py b/tests/admin_inlines/admin.py
55index 44671d0..2bc9dc5 100644
56--- a/tests/admin_inlines/admin.py
57+++ b/tests/admin_inlines/admin.py
58@@ -129,6 +129,17 @@ class ChildModel1Inline(admin.TabularInline):
59 class ChildModel2Inline(admin.StackedInline):
60     model = ChildModel2
61 
62+# admin for #19425
63+class BinaryTreeAdmin(admin.TabularInline):
64+    model = BinaryTree
65+
66+    def get_extra(self, request, obj=None, **kwargs):
67+        extra = 2
68+        if obj:
69+            return extra - obj.binarytree_set.count()
70+
71+        return extra
72+
73 # admin for #19524
74 class SightingInline(admin.TabularInline):
75     model = Sighting
76@@ -150,4 +161,5 @@ site.register(Author, AuthorAdmin)
77 site.register(CapoFamiglia, inlines=[ConsigliereInline, SottoCapoInline, ReadOnlyInlineInline])
78 site.register(ProfileCollection, inlines=[ProfileInline])
79 site.register(ParentModelWithCustomPk, inlines=[ChildModel1Inline, ChildModel2Inline])
80+site.register(BinaryTree, inlines=[BinaryTreeAdmin])
81 site.register(ExtraTerrestrial, inlines=[SightingInline])
82diff --git a/tests/admin_inlines/models.py b/tests/admin_inlines/models.py
83index 82c1c3f..d4ba0ab 100644
84--- a/tests/admin_inlines/models.py
85+++ b/tests/admin_inlines/models.py
86@@ -183,6 +183,12 @@ class ChildModel2(models.Model):
87     def get_absolute_url(self):
88         return '/child_model2/'
89 
90+
91+# Models for #19425
92+class BinaryTree(models.Model):
93+    name = models.CharField(max_length=100)
94+    parent = models.ForeignKey('self', null=True, blank=True)
95+
96 # Models for #19524
97 
98 class LifeForm(models.Model):