Show children inline in Django admin
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
In Django 1.11, I have 2 models, Foo
and Bar
:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
When I visit the Foo page in the Django admin, I want to be able to see a list of its Bars underneath it. So I do this in admin.py
:
class BarInline(admin.StackedInline):
model = Bar
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name')
inlines = [BarInline]
But what I really want is a list of clickable links to a separate page where I can edit each Bar (as well as a Add button to add a new Bar to this Foo). I.e. I don't want the entire inline form. How is this possible in Django?
python django
add a comment |
In Django 1.11, I have 2 models, Foo
and Bar
:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
When I visit the Foo page in the Django admin, I want to be able to see a list of its Bars underneath it. So I do this in admin.py
:
class BarInline(admin.StackedInline):
model = Bar
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name')
inlines = [BarInline]
But what I really want is a list of clickable links to a separate page where I can edit each Bar (as well as a Add button to add a new Bar to this Foo). I.e. I don't want the entire inline form. How is this possible in Django?
python django
add a comment |
In Django 1.11, I have 2 models, Foo
and Bar
:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
When I visit the Foo page in the Django admin, I want to be able to see a list of its Bars underneath it. So I do this in admin.py
:
class BarInline(admin.StackedInline):
model = Bar
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name')
inlines = [BarInline]
But what I really want is a list of clickable links to a separate page where I can edit each Bar (as well as a Add button to add a new Bar to this Foo). I.e. I don't want the entire inline form. How is this possible in Django?
python django
In Django 1.11, I have 2 models, Foo
and Bar
:
class Foo(models.Model):
name = models.CharField()
class Bar(models.Model):
name = models.CharField()
foo = models.ForeignKey(Foo)
When I visit the Foo page in the Django admin, I want to be able to see a list of its Bars underneath it. So I do this in admin.py
:
class BarInline(admin.StackedInline):
model = Bar
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name')
inlines = [BarInline]
But what I really want is a list of clickable links to a separate page where I can edit each Bar (as well as a Add button to add a new Bar to this Foo). I.e. I don't want the entire inline form. How is this possible in Django?
python django
python django
asked Jan 3 at 15:54


GluePearGluePear
2,98063263
2,98063263
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
admin.py
from django.urls import reverse
from django.utils.html import format_html_join
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', get_related, )
readonly_fields = (get_related, )
def get_related(self, instance):
obj = instance.bar_set.all()
return format_html_join(
',',
'<a href="{}">{}</a>',
((
reverse('admin:{{ app_label }}_bar_change', args=(c.id,)),
c.name
) for c in obj),
)
You can create a callable readonly field which will return the reversed admin url of each relation wrapped in the relevant html code.
This will result in something like:
"your readonly field": link1, link2, link3
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with<model_name>_set
unless you set arelated_name
. On error, this callable will fail silently, I think. Try:>>> p = Foo.objects.first()
and then>>>dir(p)
to see how you can call the relatedBar
. Otherwise, installipdb
and try to setimport pdb; pdb.set_trace() # XXX BREAKPOINT
beforereturn
to get a debugging prompt.
– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in theadmin:yourapp_bar_change
.yourapp
is the name of the application your modelBar
lies in.yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the modelBar
: Something likehttp://127.0.0.1/admin/yourapp/bar/1/change/
. I changedyourapp
to{{ app_label }}
as in the docs.
– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specifyget_related
in myfields
variable (as well as inreadonly_fields
).
– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I hadfileds='__all__'
.
– raratiru
Jan 4 at 10:17
add a comment |
You can make all the fields readonly in BarInline
.
class BarInline(admin.StackedInline):
model = Bar
readonly_fields = ('id', 'name', 'foo')
extra = 0
And for the Add functionality you can modify the inline template or more easy probably, add a custom field in FooAdmin
, something like:
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', 'custom_add_bar')
inlines = [BarInline]
def custom_add_bar(self, obj):
add_url = reverse('admin:appname_bar_add')
return mark_safe(f'<a href="{add_url}">Add Bar</a>')
Documentation for reversing admin urls
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54025679%2fshow-children-inline-in-django-admin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
admin.py
from django.urls import reverse
from django.utils.html import format_html_join
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', get_related, )
readonly_fields = (get_related, )
def get_related(self, instance):
obj = instance.bar_set.all()
return format_html_join(
',',
'<a href="{}">{}</a>',
((
reverse('admin:{{ app_label }}_bar_change', args=(c.id,)),
c.name
) for c in obj),
)
You can create a callable readonly field which will return the reversed admin url of each relation wrapped in the relevant html code.
This will result in something like:
"your readonly field": link1, link2, link3
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with<model_name>_set
unless you set arelated_name
. On error, this callable will fail silently, I think. Try:>>> p = Foo.objects.first()
and then>>>dir(p)
to see how you can call the relatedBar
. Otherwise, installipdb
and try to setimport pdb; pdb.set_trace() # XXX BREAKPOINT
beforereturn
to get a debugging prompt.
– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in theadmin:yourapp_bar_change
.yourapp
is the name of the application your modelBar
lies in.yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the modelBar
: Something likehttp://127.0.0.1/admin/yourapp/bar/1/change/
. I changedyourapp
to{{ app_label }}
as in the docs.
– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specifyget_related
in myfields
variable (as well as inreadonly_fields
).
– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I hadfileds='__all__'
.
– raratiru
Jan 4 at 10:17
add a comment |
admin.py
from django.urls import reverse
from django.utils.html import format_html_join
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', get_related, )
readonly_fields = (get_related, )
def get_related(self, instance):
obj = instance.bar_set.all()
return format_html_join(
',',
'<a href="{}">{}</a>',
((
reverse('admin:{{ app_label }}_bar_change', args=(c.id,)),
c.name
) for c in obj),
)
You can create a callable readonly field which will return the reversed admin url of each relation wrapped in the relevant html code.
This will result in something like:
"your readonly field": link1, link2, link3
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with<model_name>_set
unless you set arelated_name
. On error, this callable will fail silently, I think. Try:>>> p = Foo.objects.first()
and then>>>dir(p)
to see how you can call the relatedBar
. Otherwise, installipdb
and try to setimport pdb; pdb.set_trace() # XXX BREAKPOINT
beforereturn
to get a debugging prompt.
– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in theadmin:yourapp_bar_change
.yourapp
is the name of the application your modelBar
lies in.yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the modelBar
: Something likehttp://127.0.0.1/admin/yourapp/bar/1/change/
. I changedyourapp
to{{ app_label }}
as in the docs.
– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specifyget_related
in myfields
variable (as well as inreadonly_fields
).
– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I hadfileds='__all__'
.
– raratiru
Jan 4 at 10:17
add a comment |
admin.py
from django.urls import reverse
from django.utils.html import format_html_join
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', get_related, )
readonly_fields = (get_related, )
def get_related(self, instance):
obj = instance.bar_set.all()
return format_html_join(
',',
'<a href="{}">{}</a>',
((
reverse('admin:{{ app_label }}_bar_change', args=(c.id,)),
c.name
) for c in obj),
)
You can create a callable readonly field which will return the reversed admin url of each relation wrapped in the relevant html code.
This will result in something like:
"your readonly field": link1, link2, link3
admin.py
from django.urls import reverse
from django.utils.html import format_html_join
@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', get_related, )
readonly_fields = (get_related, )
def get_related(self, instance):
obj = instance.bar_set.all()
return format_html_join(
',',
'<a href="{}">{}</a>',
((
reverse('admin:{{ app_label }}_bar_change', args=(c.id,)),
c.name
) for c in obj),
)
You can create a callable readonly field which will return the reversed admin url of each relation wrapped in the relevant html code.
This will result in something like:
"your readonly field": link1, link2, link3
edited Jan 4 at 9:52


GluePear
2,98063263
2,98063263
answered Jan 3 at 17:50
raratiruraratiru
3,18522359
3,18522359
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with<model_name>_set
unless you set arelated_name
. On error, this callable will fail silently, I think. Try:>>> p = Foo.objects.first()
and then>>>dir(p)
to see how you can call the relatedBar
. Otherwise, installipdb
and try to setimport pdb; pdb.set_trace() # XXX BREAKPOINT
beforereturn
to get a debugging prompt.
– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in theadmin:yourapp_bar_change
.yourapp
is the name of the application your modelBar
lies in.yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the modelBar
: Something likehttp://127.0.0.1/admin/yourapp/bar/1/change/
. I changedyourapp
to{{ app_label }}
as in the docs.
– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specifyget_related
in myfields
variable (as well as inreadonly_fields
).
– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I hadfileds='__all__'
.
– raratiru
Jan 4 at 10:17
add a comment |
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with<model_name>_set
unless you set arelated_name
. On error, this callable will fail silently, I think. Try:>>> p = Foo.objects.first()
and then>>>dir(p)
to see how you can call the relatedBar
. Otherwise, installipdb
and try to setimport pdb; pdb.set_trace() # XXX BREAKPOINT
beforereturn
to get a debugging prompt.
– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in theadmin:yourapp_bar_change
.yourapp
is the name of the application your modelBar
lies in.yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the modelBar
: Something likehttp://127.0.0.1/admin/yourapp/bar/1/change/
. I changedyourapp
to{{ app_label }}
as in the docs.
– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specifyget_related
in myfields
variable (as well as inreadonly_fields
).
– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I hadfileds='__all__'
.
– raratiru
Jan 4 at 10:17
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
Thanks for the detailed response. Unfortunately this is not outputting any HTML.
– GluePear
Jan 4 at 9:04
@GluePear Reverse relations are called with
<model_name>_set
unless you set a related_name
. On error, this callable will fail silently, I think. Try: >>> p = Foo.objects.first()
and then >>>dir(p)
to see how you can call the related Bar
. Otherwise, install ipdb
and try to set import pdb; pdb.set_trace() # XXX BREAKPOINT
before return
to get a debugging prompt.– raratiru
Jan 4 at 9:16
@GluePear Reverse relations are called with
<model_name>_set
unless you set a related_name
. On error, this callable will fail silently, I think. Try: >>> p = Foo.objects.first()
and then >>>dir(p)
to see how you can call the related Bar
. Otherwise, install ipdb
and try to set import pdb; pdb.set_trace() # XXX BREAKPOINT
before return
to get a debugging prompt.– raratiru
Jan 4 at 9:16
@GluePear There is also a gotcha in the
admin:yourapp_bar_change
. yourapp
is the name of the application your model Bar
lies in. yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the model Bar
: Something like http://127.0.0.1/admin/yourapp/bar/1/change/
. I changed yourapp
to {{ app_label }}
as in the docs.– raratiru
Jan 4 at 9:28
@GluePear There is also a gotcha in the
admin:yourapp_bar_change
. yourapp
is the name of the application your model Bar
lies in. yourproject/yourapp/models.py
. You can also find it in the admin url when you change an instance of the model Bar
: Something like http://127.0.0.1/admin/yourapp/bar/1/change/
. I changed yourapp
to {{ app_label }}
as in the docs.– raratiru
Jan 4 at 9:28
Thanks for persevering. My problem was that I also needed to specify
get_related
in my fields
variable (as well as in readonly_fields
).– GluePear
Jan 4 at 9:52
Thanks for persevering. My problem was that I also needed to specify
get_related
in my fields
variable (as well as in readonly_fields
).– GluePear
Jan 4 at 9:52
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I had
fileds='__all__'
.– raratiru
Jan 4 at 10:17
@GluePear Oh, indeed, I blindly copy-pasted the code, in my implementation I had
fileds='__all__'
.– raratiru
Jan 4 at 10:17
add a comment |
You can make all the fields readonly in BarInline
.
class BarInline(admin.StackedInline):
model = Bar
readonly_fields = ('id', 'name', 'foo')
extra = 0
And for the Add functionality you can modify the inline template or more easy probably, add a custom field in FooAdmin
, something like:
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', 'custom_add_bar')
inlines = [BarInline]
def custom_add_bar(self, obj):
add_url = reverse('admin:appname_bar_add')
return mark_safe(f'<a href="{add_url}">Add Bar</a>')
Documentation for reversing admin urls
add a comment |
You can make all the fields readonly in BarInline
.
class BarInline(admin.StackedInline):
model = Bar
readonly_fields = ('id', 'name', 'foo')
extra = 0
And for the Add functionality you can modify the inline template or more easy probably, add a custom field in FooAdmin
, something like:
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', 'custom_add_bar')
inlines = [BarInline]
def custom_add_bar(self, obj):
add_url = reverse('admin:appname_bar_add')
return mark_safe(f'<a href="{add_url}">Add Bar</a>')
Documentation for reversing admin urls
add a comment |
You can make all the fields readonly in BarInline
.
class BarInline(admin.StackedInline):
model = Bar
readonly_fields = ('id', 'name', 'foo')
extra = 0
And for the Add functionality you can modify the inline template or more easy probably, add a custom field in FooAdmin
, something like:
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', 'custom_add_bar')
inlines = [BarInline]
def custom_add_bar(self, obj):
add_url = reverse('admin:appname_bar_add')
return mark_safe(f'<a href="{add_url}">Add Bar</a>')
Documentation for reversing admin urls
You can make all the fields readonly in BarInline
.
class BarInline(admin.StackedInline):
model = Bar
readonly_fields = ('id', 'name', 'foo')
extra = 0
And for the Add functionality you can modify the inline template or more easy probably, add a custom field in FooAdmin
, something like:
class FooAdmin(admin.ModelAdmin):
list_display = ('name')
fields = ('name', 'custom_add_bar')
inlines = [BarInline]
def custom_add_bar(self, obj):
add_url = reverse('admin:appname_bar_add')
return mark_safe(f'<a href="{add_url}">Add Bar</a>')
Documentation for reversing admin urls
answered Jan 3 at 17:27


grouchoboygrouchoboy
49639
49639
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54025679%2fshow-children-inline-in-django-admin%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown