Reputation: 7752
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
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
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
Reputation: 127
# 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)
# 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
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
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