Ticket #18388: patch_ticket_18338.3.txt

File patch_ticket_18338.3.txt, 4.4 KB (added by areski, 22 months ago)
Line 
1diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
2index 7373837..487fc4e 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,17 @@ 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+        if not isinstance(self.extra, int):
21+            raise ImproperlyConfigured("'%s.extra' should be a integer."
22+                                       % self.__class__.__name__)
23+        return self.extra
24+
25+    def get_max_num(self, request, obj=None, **kwargs):
26+        """Get the max number of extra inline forms needed"""
27+        return self.max_num
28+
29     def get_formset(self, request, obj=None, **kwargs):
30         """Returns a BaseInlineFormSet class for use in admin add/change views."""
31         if self.declared_fieldsets:
32@@ -1493,8 +1504,8 @@ class InlineModelAdmin(BaseModelAdmin):
33             "fields": fields,
34             "exclude": exclude,
35             "formfield_callback": partial(self.formfield_for_dbfield, request=request),
36-            "extra": self.extra,
37-            "max_num": self.max_num,
38+            "extra": self.get_extra(request, obj, *kwargs),
39+            "max_num": self.get_max_num(request, obj, *kwargs),
40             "can_delete": can_delete,
41         }
42 
43diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
44index 8d65f96..06b5055 100644
45--- a/django/contrib/admin/validation.py
46+++ b/django/contrib/admin/validation.py
47@@ -199,11 +199,6 @@ def validate_inline(cls, parent, parent_model):
48 
49     fk = _get_foreign_key(parent_model, cls.model, fk_name=cls.fk_name, can_fail=True)
50 
51-    # extra = 3
52-    if not isinstance(cls.extra, int):
53-        raise ImproperlyConfigured("'%s.extra' should be a integer."
54-                % cls.__name__)
55-
56     # max_num = None
57     max_num = getattr(cls, 'max_num', None)
58     if max_num is not None and not isinstance(max_num, int):
59diff --git a/tests/admin_inlines/admin.py b/tests/admin_inlines/admin.py
60index 44671d0..2f88248 100644
61--- a/tests/admin_inlines/admin.py
62+++ b/tests/admin_inlines/admin.py
63@@ -129,6 +129,22 @@ class ChildModel1Inline(admin.TabularInline):
64 class ChildModel2Inline(admin.StackedInline):
65     model = ChildModel2
66 
67+# admin for #19425 and #18388
68+class BinaryTreeAdmin(admin.TabularInline):
69+    model = BinaryTree
70+
71+    def get_extra(self, request, obj=None, **kwargs):
72+        extra = 2
73+        if obj:
74+            return extra - obj.binarytree_set.count()
75+        return extra
76+
77+    def get_max_num(self, request, obj=None, **kwargs):
78+        max_num = 3
79+        if obj:
80+            return max_num - obj.binarytree_set.count()
81+        return max_num
82+
83 # admin for #19524
84 class SightingInline(admin.TabularInline):
85     model = Sighting
86@@ -150,4 +166,5 @@ site.register(Author, AuthorAdmin)
87 site.register(CapoFamiglia, inlines=[ConsigliereInline, SottoCapoInline, ReadOnlyInlineInline])
88 site.register(ProfileCollection, inlines=[ProfileInline])
89 site.register(ParentModelWithCustomPk, inlines=[ChildModel1Inline, ChildModel2Inline])
90+site.register(BinaryTree, inlines=[BinaryTreeAdmin])
91 site.register(ExtraTerrestrial, inlines=[SightingInline])
92diff --git a/tests/admin_inlines/models.py b/tests/admin_inlines/models.py
93index 82c1c3f..d4ba0ab 100644
94--- a/tests/admin_inlines/models.py
95+++ b/tests/admin_inlines/models.py
96@@ -183,6 +183,12 @@ class ChildModel2(models.Model):
97     def get_absolute_url(self):
98         return '/child_model2/'
99 
100+
101+# Models for #19425
102+class BinaryTree(models.Model):
103+    name = models.CharField(max_length=100)
104+    parent = models.ForeignKey('self', null=True, blank=True)
105+
106 # Models for #19524
107 
108 class LifeForm(models.Model):
Back to Top