Django Admin nested inline

前端 未结 6 1079
耶瑟儿~
耶瑟儿~ 2020-12-01 02:30

I need a nested django admin inline, which I can include the date field inlines in an other inline like below.

I have the models below:

class Person         


        
相关标签:
6条回答
  • 2020-12-01 03:09

    AFAIK, you can't have a second level of inlines in the default Django admin.

    The Django admin is just a normal Django application, so nothing prevents you from implementing a second level of nested forms, but IMHO it would be a kind of convoluted design to implement. Perhaps that is why there is no provision for it.

    0 讨论(0)
  • 2020-12-01 03:11

    More universal solution

    from django.utils.safestring import mark_safe
    from django.core.urlresolvers import reverse
    class EditLinkToInlineObject(object):
        def edit_link(self, instance):
            url = reverse('admin:%s_%s_change' % (
                instance._meta.app_label,  instance._meta.model_name),  args=[instance.pk] )
            if instance.pk:
                return mark_safe(u'<a href="{u}">edit</a>'.format(u=url))
            else:
                return ''
    
    class MyModelInline(EditLinkToInlineObject, admin.TabularInline):
        model = MyModel
        readonly_fields = ('edit_link', )
    
    class MySecondModelAdmin(admin.ModelAdmin):
        inlines = (MyModelInline, )
    
    admin.site.register(MyModel)
    admin.site.register(MySecondModel, MySecondModelAdmin)
    
    0 讨论(0)
  • 2020-12-01 03:13
    pip install django-nested-inline
    

    This package should do what you need.

    0 讨论(0)
  • 2020-12-01 03:16

    I used the solution provided by @bigzbig (thank you).

    I also wanted to go back to the first list page once changes had been saved so added:

    class MyModelInline(EditLinkToInlineObject, admin.TabularInline):
        model = MyModel
        readonly_fields = ('edit_link', )
    
        def response_post_save_change(self, request, obj):
            my_second_model_id = MyModel.objects.get(pk=obj.pk).my_second_model_id
            return redirect("/admin/mysite/mysecondmodel/%s/change/" % (my_second_model_id))
    
    0 讨论(0)
  • 2020-12-01 03:28

    Nested inlines are provided at: https://github.com/BertrandBordage/django-super-inlines/

    pip install django-super-inlines
    
    0 讨论(0)
  • 2020-12-01 03:34

    There has been some movement in https://code.djangoproject.com/ticket/9025 recently, but I wouldn't hold my breath.

    One common way around this is to link to an admin between first and second (or second and third) level by having both a ModelAdmin and an Inline for the same model:

    Give Certificate a ModelAdmin with TrainingDate as an inline. Give CertificateInline an additional field "Details" which is a link to its ModelAdmin change form.

    models.py:

    from django.core import urlresolvers
    
    class Certificate(models.Model):
    
        # ...
    
        def changeform_link(self):
            if self.id:
                # Replace "myapp" with the name of the app containing
                # your Certificate model:
                changeform_url = urlresolvers.reverse(
                    'admin:myapp_certificate_change', args=(self.id,)
                )
                return u'<a href="%s" target="_blank">Details</a>' % changeform_url
            return u''
        changeform_link.allow_tags = True
        changeform_link.short_description = ''   # omit column header
    

    admin.py:

    # Certificate change form has training dates as inline
    
    class TrainingDateInline(admin.StackedInline):
        model = TrainingDate
    
    class CertificateAdmin(admin.ModelAdmin):
        inlines = [TrainingDateInline,]
    admin.site.register(Certificate ,CertificateAdmin)
    
    # Person has Certificates inline but rather
    # than nesting inlines (not possible), shows a link to
    # its own ModelAdmin's change form, for accessing TrainingDates:
    
    class CertificateLinkInline(admin.TabularInline):
        model = Certificate
        # Whichever fields you want: (I usually use only a couple
        # needed to identify the entry)
        fields = ('cerfificate_no', 'certificate_date', 'changeform_link')
        readonly_fields = ('changeform_link', )
    
    class PersonAdmin(admin.ModelAdmin):
        inlines = [CertificateLinkInline,]
    admin.site.register(Person, PersonAdmin)
    
    0 讨论(0)
提交回复
热议问题