Created
July 4, 2011 21:47
-
-
Save razum2um/1063986 to your computer and use it in GitHub Desktop.
django nested sets (level<=3) support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From bbb53d927c0949246c1735baaf34aa4261cfbb3c Mon Sep 17 00:00:00 2001 | |
From: Vlad Bokov <[email protected]> | |
Date: Tue, 5 Jul 2011 04:14:42 +0700 | |
Subject: [PATCH] nested sets (level<=3) support | |
--- | |
django/contrib/admin/options.py | 36 +++++++++++++++ | |
.../admin/templates/admin/edit_inline/nested.html | 48 ++++++++++++++++++++ | |
.../admin/templates/admin/edit_inline/tabular.html | 13 +++++- | |
3 files changed, 96 insertions(+), 1 deletions(-) | |
create mode 100644 django/contrib/admin/templates/admin/edit_inline/nested.html | |
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py | |
index 550f46a..8dad2f2 100644 | |
--- a/django/contrib/admin/options.py | |
+++ b/django/contrib/admin/options.py | |
@@ -937,6 +937,17 @@ class ModelAdmin(BaseModelAdmin): | |
formset = FormSet(instance=self.model(), prefix=prefix, | |
queryset=inline.queryset(request)) | |
formsets.append(formset) | |
+ for inline in self.inline_instances: | |
+ # If this is the inline that matches this formset, and | |
+ # we have some nested inlines to deal with, then we need | |
+ # to get the relevant formset for each of the forms in | |
+ # the current formset. | |
+ if inline.inlines and inline.model == formset.model: | |
+ for nested in inline.inline_instances: | |
+ for the_form in formset.forms: | |
+ InlineFormSet = nested.get_formset(request, the_form.instance) | |
+ prefix = "%s-%s" % (the_form.prefix, InlineFormSet.get_default_prefix()) | |
+ formsets.append(InlineFormSet(request.POST, request.FILES, instance=the_form.instance, prefix=prefix)) | |
adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), | |
self.get_prepopulated_fields(request), | |
@@ -1041,6 +1052,14 @@ class ModelAdmin(BaseModelAdmin): | |
prepopulated = dict(inline.get_prepopulated_fields(request, obj)) | |
inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, | |
fieldsets, prepopulated, readonly, model_admin=self) | |
+ if inline.inlines: | |
+ for form in formset.forms: | |
+ if form.instance.pk: | |
+ instance = form.instance | |
+ else: | |
+ instance = None | |
+ form.inlines = inline.get_inlines(request, instance, prefix=form.prefix) | |
+ inline_admin_formset.inlines = inline.get_inlines(request) | |
inline_admin_formsets.append(inline_admin_formset) | |
media = media + inline_admin_formset.media | |
@@ -1315,6 +1334,7 @@ class InlineModelAdmin(BaseModelAdmin): | |
verbose_name = None | |
verbose_name_plural = None | |
can_delete = True | |
+ inlines = [] | |
def __init__(self, parent_model, admin_site): | |
self.admin_site = admin_site | |
@@ -1325,6 +1345,10 @@ class InlineModelAdmin(BaseModelAdmin): | |
self.verbose_name = self.model._meta.verbose_name | |
if self.verbose_name_plural is None: | |
self.verbose_name_plural = self.model._meta.verbose_name_plural | |
+ self.inline_instances = [] | |
+ for inline_class in self.inlines: | |
+ inline_instance = inline_class(self.model, self.admin_site) | |
+ self.inline_instances.append(inline_instance) | |
def _media(self): | |
js = ['jquery.min.js', 'jquery.init.js', 'inlines.min.js'] | |
@@ -1370,6 +1394,18 @@ class InlineModelAdmin(BaseModelAdmin): | |
fields = form.base_fields.keys() + list(self.get_readonly_fields(request, obj)) | |
return [(None, {'fields': fields})] | |
+ def get_inlines(self, request, obj=None, prefix=None): | |
+ nested_inlines = [] | |
+ for inline in self.inline_instances: | |
+ FormSet = inline.get_formset(request, obj) | |
+ prefix = "%s-%s" % (prefix, FormSet.get_default_prefix()) | |
+ formset = FormSet(instance=obj, prefix=prefix) | |
+ fieldsets = list(inline.get_fieldsets(request, obj)) | |
+ nested_inline = helpers.InlineAdminFormSet(inline, formset, fieldsets) | |
+ nested_inlines.append(nested_inline) | |
+ return nested_inlines | |
+ | |
+ | |
class StackedInline(InlineModelAdmin): | |
template = 'admin/edit_inline/stacked.html' | |
diff --git a/django/contrib/admin/templates/admin/edit_inline/nested.html b/django/contrib/admin/templates/admin/edit_inline/nested.html | |
new file mode 100644 | |
index 0000000..a8d4b74 | |
--- /dev/null | |
+++ b/django/contrib/admin/templates/admin/edit_inline/nested.html | |
@@ -0,0 +1,48 @@ | |
+<td> | |
+ {{ nested.formset.management_form }} | |
+ <table> | |
+ <thead> | |
+ <tr> | |
+ {% for field in nested.fields %} | |
+ <th {% if forloop.first %}colspan="2"{% endif %}>{{ field.label|capfirst }}</th> | |
+ {% endfor %} | |
+ {% if nested.formset.can_delete %} | |
+ <th>Delete?</th> | |
+ {% endif %} | |
+ </tr> | |
+ </thead> | |
+ | |
+ <tbody> | |
+ {% for formset in nested %} | |
+ {% if formset.form.non_field_errors %} | |
+ <tr><td colspan="{{ formset.field_count }}"> | |
+ {{ form.form.non_field_errors }} | |
+ </td></tr> | |
+ {% endif %} | |
+ <tr class="{% if formset.original %}has_original{% endif %}"> | |
+ <td class="original"> | |
+ {% if formset.original %}<p style="position:relative;"> | |
+ {{ formset.original }} | |
+ </p>{% endif %} | |
+ {% if formset.has_auto_field %} | |
+ {{ formset.pk_field.field }} | |
+ {% endif %}{{ formset.fk_field.field }} | |
+ </td> | |
+ {% for fieldset in formset %} | |
+ {% for line in fieldset %} | |
+ {% for field in line %} | |
+ <td class="{{ field.field.name }}"> | |
+ {{ field.field.errors.as_ul}} | |
+ {{ field.field }} | |
+ </td> | |
+ {% endfor %} | |
+ {% endfor %} | |
+ {% endfor %} | |
+ {% if formset.original and nested.formset.can_delete %} | |
+ <td class="delete">{{ formset.deletion_field.field }}</td> | |
+ {% endif %} | |
+ </tr> | |
+ {% endfor %} | |
+ </tbody> | |
+ </table> | |
+</td> | |
\ No newline at end of file | |
diff --git a/django/contrib/admin/templates/admin/edit_inline/tabular.html b/django/contrib/admin/templates/admin/edit_inline/tabular.html | |
index 8294227..bef900e 100644 | |
--- a/django/contrib/admin/templates/admin/edit_inline/tabular.html | |
+++ b/django/contrib/admin/templates/admin/edit_inline/tabular.html | |
@@ -13,8 +13,12 @@ | |
{% endif %} | |
{% endfor %} | |
{% if inline_admin_formset.formset.can_delete %}<th>{% trans "Delete?" %}</th>{% endif %} | |
+ {% if inline_admin_formset.inlines %} | |
+ {% for nested in inline_admin_formset.inlines %} | |
+ <th>{{ nested.opts.verbose_name_plural|capfirst }}</th> | |
+ {% endfor %} | |
+ {% endif %} | |
</tr></thead> | |
- | |
<tbody> | |
{% for inline_admin_form in inline_admin_formset %} | |
{% if inline_admin_form.form.non_field_errors %} | |
@@ -22,6 +26,7 @@ | |
{% endif %} | |
<tr class="{% cycle "row1" "row2" %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last %} empty-form{% endif %}" | |
id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}"> | |
+ | |
<td class="original"> | |
{% if inline_admin_form.original or inline_admin_form.show_url %}<p> | |
{% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %} | |
@@ -56,6 +61,12 @@ | |
{% if inline_admin_formset.formset.can_delete %} | |
<td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td> | |
{% endif %} | |
+ | |
+ {% if inline_admin_formset.inlines %} | |
+ {% for nested in inline_admin_form.form.inlines %} | |
+ {% include 'admin/edit_inline/nested.html' %} | |
+ {% endfor %} | |
+ {% endif %} | |
</tr> | |
{% endfor %} | |
</tbody> | |
-- | |
1.7.3.4 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment