#20702: Using ModelAdmin.get_formsets() to filter inlines is broken. -------------------------------------+------------------------------------- Reporter: stanislas.guerra@… | Owner: Type: Bug | CodenameTim Component: contrib.admin | Status: assigned Severity: Normal | Version: 1.4 Keywords: admin inlines | Resolution: get_formsets | Triage Stage: Accepted Has patch: 1 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- Changes (by CodenameTim):
* needs_better_patch: 1 => 0 Comment: Good point. I didn't think of that. I've got a solution, though I'm not sure of how to handle the naming of the methods. In order to get {{{ get_formsets()}}} to trigger a deprecation warning, I had to put the logic into the helper function {{{ _get_formsets()}}} and then call that with {{{ get_formsets()}}} where the warning is raised. Otherwise, the deprecation warning wouldn't be triggered until that generator had {{{ next()}}} called. Then in order to use either the old {{{ get_formsets()}}} method or the new {{{ get_formsets_with_inlines()}}} method result, I had to zip the result of {{{ get_formsets()}}} with the inlines when it was returned. I brought the fetching of the inlines into the method since they were simply being passed around in the methods that were calling {{{ get_formsets_with_inlines()}}}. I can move them back out if needed. Note that this does change the interface of {{{ _create_formsets()}}} but that's an internal method. The changes to it were removing of the inline_instances parameter and having it return a tuple containing the list of formsets and the list of used inline instances. For the original bug, the solution's admin.py would now look like the following, overriding {{{get_formsets_with_inlines()}}}: {{{ from django.contrib import admin from .models import Bar, Baz, Foo class BarInline(admin.TabularInline): model = Bar fields = ("title", "surname") class BazInline(admin.TabularInline): model = Baz fields = ("country", "zipcode") class FooAdmin(admin.ModelAdmin): inlines = [BarInline, BazInline] def get_formsets_with_inlines(self, request, obj=None): for inline in self.get_inline_instances(request): # Only in change view. if obj is None: continue if isinstance(inline, BarInline) and obj.condition(): yield inline.get_formset(request, obj), inline elif isinstance(inline, BazInline) and obj.another_condition(): yield inline.get_formset(request, obj), inline admin.site.register(Bar) admin.site.register(Baz) admin.site.register(Foo, FooAdmin) }}} Commit (on master): https://github.com/tim- schilling/django/commit/5eac26f353533f6eb68779917d0885938ee2eebf I've also updated the documentation. I'm not sure if I missed any steps, this is my first time working on a ticket. -- Ticket URL: <https://code.djangoproject.com/ticket/20702#comment:7> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/084.feb78ccd1f3a6a0e40767712fa7bbf1c%40djangoproject.com. For more options, visit https://groups.google.com/groups/opt_out.