pynovice
pynovice

Reputation: 7752

How to position inlines in Django Admin in the list_display property?

I have two tables related Quiz and Difficulty_level:

I have created inline in admin.py like this:

class DifficultyLevelInline(admin.TabularInline):
    model = DifficultyLevel

and included in QuizAdmin

To arrange the list order, I would do:

  list_display = ('name', 'description', 'publication_date', 'category', 'is_active', 'is_premium')

How can I add inlines in the list_display order. I want to display The DifficultyLevelInline before category.

Upvotes: 6

Views: 6235

Answers (5)

frnhr
frnhr

Reputation: 12903

I found an app for exactly this: https://github.com/robertkovac/django-fieldsets-with-inlines

class MyModelAdmin(FieldsetsInlineMixin, admin.ModelAdmin):
    ...
    fieldsets_with_inlines = [
        (None, {
            'fields': [
                'name',
                'slug',
            ],
        }),
        RelatedThingInline,
        ('Moar Feelds', {
            'is_great',
            'is_neet',
        }),
    ]

Works for me on Django 4.1.

Upvotes: 0

Mohammed Rishad
Mohammed Rishad

Reputation: 335

I found a solution here: https://blog.devgenius.io/django-admin-dynamic-inline-positioning-7208596479ce

class MyAdmin(admin.ModelAdmin):
    list_display = ('name', 'description', 'difficulty_level_inline', 'publication_date', 'category', 'is_active', 'is_premium')
    inlines = (DifficultyLevelInline,)

    def difficulty_level_inline(self, *args, **kwargs):
        context = getattr(self.response, 'context_data', None) or {}
        inline = context['inline_admin_formset'] = context['inline_admin_formsets'].pop(0)
        return get_template(inline.opts.template).render(context, self.request)

    def render_change_form(self, request, *args, **kwargs):
      self.request = request
      self.response = super().render_change_form(request, *args, **kwargs)
      return self.response

Upvotes: 1

bode liang
bode liang

Reputation: 127

  • Suppose here is your inline model:
# models.py
from django.contrib.auth.models import Group


class MoreGroup(models.Model):
    group = models.OneToOneField(Group, on_delete=models.CASCADE, related_name='more_group')
    explain = models.CharField(verbose_name="explain_info", max_length=64, blank=True, null=True)
    active = models.BooleanField(verbose_name="is_actived", default=True, blank=True, null=True)

  • then do this:
# admin.py
from . import models


class MoreGroupInline(admin.StackedInline):
    model = models.MoreGroup
    can_delete = False
    verbose_name_plural = 'more_info'


class MyGroupAdmin(GroupAdmin):
    list_display = ['id', 'name', 'get_inline_info']
    def get_inline_info(self, obj) -> str:
        mg = models.MoreGroup.objects.filter(group=obj)
        if mg.count():
            return mg[0].explain
        else:
            return '-'
    get_inline_info.short_description = 'explain_info'

admin.site.register(models.Group, MyGroupAdmin)

Upvotes: 0

blueyed
blueyed

Reputation: 27858

Grapelli supports it: https://django-grappelli.readthedocs.org/en/latest/customization.html#rearrange-inlines

Basically, it uses a placeholder via fieldsets and then moves them HTML via JavaScript: https://github.com/sehmaschine/django-grappelli/blob/master/grappelli/templates/admin/change_form.html#L90-96 (search for placeholder, if the lines do not match anymore).

The same can be done by injecting custom javascript yourself (with or without using fieldsets as placeholders).

Upvotes: 4

fsw
fsw

Reputation: 3695

Unfortunately this is not possible using the default template.

If you take a look at change_form template:

https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html

You can see that inlines are always rendered after fieldsets.

One way to get around this would be to use other template:

class MyAdmin(admin.ModelAdmin):
    list_display = ('name', 'description', 'publication_date', 'category', 'is_active', 'is_premium')
    inlines = (DifficultyLevelInline,)
    change_form_template = "my_change_form.html"

Upvotes: 6

Related Questions