29👍
UPDATE:
Since Django 1.8, this is built in.
See this answer and the official documentation.
OLD ANSWER:
At the end I found a simple solution.
I create a new template called linked.html
that is a copy of tabular.html
and I added this code to create the link.
{% if inline_admin_form.original.pk %}
<td class="{{ field.field.name }}">
<a href="/admin/{{ app_label }}/{{ inline_admin_formset.opts.admin_model_path }}/{{ inline_admin_form.original.pk }}/">Full record</a>
</td>
{% endif %}
then I created a new model LinkedInline
inheriting InlineModelAdmin
#override of the InlineModelAdmin to support the link in the tabular inline
class LinkedInline(admin.options.InlineModelAdmin):
template = "admin/linked.html"
admin_model_path = None
def __init__(self, *args):
super(LinkedInline, self).__init__(*args)
if self.admin_model_path is None:
self.admin_model_path = self.model.__name__.lower()
Then when I define a new inline, I have only to use my LinkedInline
instead of the normal InlineModelAdmin
.
I hope it can be useful for other people.
Giovanni
25👍
Update:
As of Django 1.8, this is now built-in.
Answer for Django <= 1.7:
Keep your code in models.py with conditional case:
def selflink(self):
if self.id:
return "<a href='/link/to/volume/%s' target='_blank'>Edit</a>" % str(self.id)
else:
return "Not present"
selflink.allow_tags = True
In admin.py, add selflink as readonly field:
class VolumeInline(admin.TabularInline):
readonly_fields = ['selflink',]
model = Volume
That worked for me.
- [Django]-Django equivalent of SQL not in
- [Django]-Project design / FS layout for large django projects
- [Django]-Django: Access given field's choices tuple
14👍
Here’s a reusable mixin based on some of the other answers. This is handy because it works with both Tabular and Stacked inlines, and doesn’t cruft up your model or admin code.
# put this somewhere like admin_helpers.py
from django.core.urlresolvers import reverse
class InlineEditLinkMixin(object):
readonly_fields = ['edit_details']
edit_label = "Edit"
def edit_details(self, obj):
if obj.id:
opts = self.model._meta
return "<a href='%s' target='_blank'>%s</a>" % (reverse(
'admin:%s_%s_change' % (opts.app_label, opts.object_name.lower()),
args=[obj.id]
), self.edit_label)
else:
return "(save to edit details)"
edit_details.allow_tags = True
# admin.py
class VolumeInline(InlineEditLinkMixin, admin.TabularInline):
fields = ['foo', 'bar', 'edit_details']
class JournalAdmin(admin.ModelAdmin):
inlines = [VolumeInline]
class ScanInfoInline(InlineEditLinkMixin, admin.StackedInline):
fields = ['foo', 'bar', 'edit_details']
class JournalAdmin(admin.ModelAdmin):
inlines = [ScanInfoInline]
- [Django]-How to expire Django session in 5minutes?
- [Django]-Django "xxxxxx Object" display customization in admin action sidebar
- [Django]-How to stop celery worker process
9👍
In Django 1.8+ this is now much easier. Just add show_change_link = True
to your TabularInline
or StackedInline
subclass, like this:
class VolumeInline(admin.TabularInline):
fields = ['volumenumber']
model = Volume
extra = 1
show_change_link = True
And Django will automatically add a link to the full change form for each inline item, if the model has its own registered ModelAdmin
.
- [Django]-How to update an object from edit form in Django?
- [Django]-How do I use a dictionary to update fields in Django models?
- [Django]-How do I change the range of the x-axis with datetime?
3👍
Did you try the Reversing admin URL system ?
That could give something like that (in the journal page):
<ul>
{% for volume in original.volume_set.all %}
<li>
<a href="{% url admin:yourapp_volume_change volume.id %}">Edit {{ volume }}
</a>
</li>
{% endfor %}
</ul>
- [Django]-UnicodeDecodeError: 'ascii' codec can't decode byte 0xd1 in position 2: ordinal not in range(128)
- [Django]-What are the differences between setUpClass, setUpTestData and setUp in TestCase class?
- [Django]-The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting
2👍
After some fiddling, I was able to make this work in an InlineAdmin and a TabularInline, using reverse(). At least with TabularInline, the field you want to link must be listed in ‘readonly_fields’
# create a read-only inline with the first field linked
from django.core import urlresolvers
class YOUR_MODEL_Inline(LinkedTabularInline):
max_num = 0 # remove the "Add another ..." link
model = YOUR_MODEL_NAME
fk_name = "YOUR_FOREIGN_KEY_NAME"
fields = [ 'link_name', ] # , 'field1', 'field2', 'etc' ]
readonly_fields = fields
can_delete = False
def link_name(self, obj):
if obj.pk:
url = urlresolvers.reverse('admin:%s_%s_change'
% (obj._meta.app_label, obj._meta.module_name), args=[obj.id])
# obj.MODEL_FIELD can be a text string or whatever you want
return '<a href="{0}">{1}</a>'.format(url, obj.MODEL_FIELD)
link_name.allow_tags = True
link_name.short_description = "MODEL_FIELD"
If you want to link to the change list instead of the change view, you can modify the reverse() call. changelist does not require an object id.
url = urlresolvers.reverse('admin:%s_%s_changelist'
% (obj._meta.app_label, obj._meta.module_name))
return '<a href="{0}">{1}</a>'.format(url, obj.name)
And if you want to link to a subset of objects, you can add parameters to the URL:
return '<a href="{0}?YOUR_MODEL_FIELD__id__exact={1}">{2}</a>'.format(url, obj.id, obj.name)
- [Django]-Rerun a Django data migration
- [Django]-Overriding the save method in Django ModelForm
- [Django]-Django Rest Framework: Disable field update after object is created