25π
Add this to your model:
def user_link(self):
return '<a href="%s">%s</a>' % (reverse("admin:auth_user_change", args=(self.user.id,)) , escape(self.user))
user_link.allow_tags = True
user_link.short_description = "User"
You might also need to add the following to the top of models.py
:
from django.template.defaultfilters import escape
from django.core.urls import reverse
In admin.py
, in list_display
, add user_link
:
list_display = ('name', 'user_link', )
No need for list_display_links
.
92π
Modifying your model isnβt necessary, and itβs actually a bad practice (adding admin-specific view-logic into your models? Yuck!) It may not even be possible in some scenarios.
Luckily, it can all be achieved from the ModelAdmin class:
from django.urls import reverse
from django.utils.safestring import mark_safe
class PageAdmin(admin.ModelAdmin):
# Add it to the list view:
list_display = ('name', 'user_link', )
# Add it to the details view:
readonly_fields = ('user_link',)
def user_link(self, obj):
return mark_safe('<a href="{}">{}</a>'.format(
reverse("admin:auth_user_change", args=(obj.user.pk,)),
obj.user.email
))
user_link.short_description = 'user'
admin.site.register(Page, PageAdmin)
Edit 2016-01-17:
Updated answer to use make_safe
, since allow_tags
is now deprecated.
Edit 2019-06-14:
Updated answer to use django.urls
, since as of Django 1.10 django.core.urls
has been deprecated.
- [Django]-How to add an model instance to a django queryset?
- [Django]-Django migration with uuid field generates duplicated values
- [Django]-How to backup a django db
18π
You need to use format_html for modern versions of django
@admin.register(models.Foo)
class FooAdmin(admin.ModelAdmin):
list_display = ('ts', 'bar_link',)
def bar_link(self, item):
from django.shortcuts import resolve_url
from django.contrib.admin.templatetags.admin_urls import admin_urlname
url = resolve_url(admin_urlname(models.Bar._meta, 'change'), item.bar.id)
return format_html(
'<a href="{url}">{name}</a>'.format(url=url, name=str(item.bar))
)
- [Django]-Update to Django 1.8 β AttributeError: django.test.TestCase has no attribute 'cls_atomics'
- [Django]-What is the most efficient way to store a list in the Django models?
- [Django]-What is the purpose of apps.py in Django 1.9?
14π
I ended up with a simple helper:
from django.shortcuts import resolve_url
from django.utils.safestring import SafeText
from django.contrib.admin.templatetags.admin_urls import admin_urlname
from django.utils.html import format_html
def model_admin_url(obj: Model, name: str = None) -> str:
url = resolve_url(admin_urlname(obj._meta, SafeText("change")), obj.pk)
return format_html('<a href="{}">{}</a>', url, name or str(obj))
Then you can use the helper in your model-admin:
class MyAdmin(admin.ModelAdmin):
readonly_field = ["my_link"]
def my_link(self, obj):
return model_admin_url(obj.my_foreign_key)
- [Django]-Profiling Django
- [Django]-Linking to the django admin site
- [Django]-Django β makemigrations β No changes detected
8π
I needed this for a lot of my admin pages, so I created a mixin for it that handles different use cases:
pip install django-admin-relation-links
Then:
from django.contrib import admin
from django_admin_relation_links import AdminChangeLinksMixin
@admin.register(Group)
class MyModelAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
# ...
change_links = ['field_name']
See the GitHub page for more info. Try it out and let me know how it works out!
- [Django]-Django: dependencies reference nonexistent parent node
- [Django]-IOS app with Django
- [Django]-Programmatically saving image to Django ImageField
5π
I decided to make a simple admin mixin that looks like this (see docstring for usage):
from django.contrib.contenttypes.models import ContentType
from django.utils.html import format_html
from rest_framework.reverse import reverse
class RelatedObjectLinkMixin(object):
"""
Generate links to related links. Add this mixin to a Django admin model. Add a 'link_fields' attribute to the admin
containing a list of related model fields and then add the attribute name with a '_link' suffix to the
list_display attribute. For Example a Student model with a 'teacher' attribute would have an Admin class like this:
class StudentAdmin(RelatedObjectLinkMixin, ...):
link_fields = ['teacher']
list_display = [
...
'teacher_link'
...
]
"""
link_fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.link_fields:
for field_name in self.link_fields:
func_name = field_name + '_link'
setattr(self, func_name, self._generate_link_func(field_name))
def _generate_link_func(self, field_name):
def _func(obj, *args, **kwargs):
related_obj = getattr(obj, field_name)
if related_obj:
content_type = ContentType.objects.get_for_model(related_obj.__class__)
url_name = 'admin:%s_%s_change' % (content_type.app_label, content_type.model)
url = reverse(url_name, args=[related_obj.pk])
return format_html('<a href="{}" class="changelink">{}</a>', url, str(related_obj))
else:
return None
return _func
- [Django]-Django: Reverse for 'detail' with arguments '('',)' and keyword arguments '{}' not found
- [Django]-How to redirect with post data (Django)
- [Django]-How to use regex in django query
2π
If anyone is trying to do this with inline admin, consider a property called show_change_link since Django 1.8.
Your code could then look like this:
class QuestionInline(admin.TabularInline):
model = Question
extra = 1
show_change_link = True
class TestAdmin(admin.ModelAdmin):
inlines = (QuestionInline,)
admin.site.register(Test, TestAdmin)
This will add a change/update link for each foreign key relationship in the adminβs inline section.
- [Django]-Django "Cannot add or update a child row: a foreign key constraint fails"
- [Django]-Django-Bower + Foundation 5 + SASS, How to configure?
- [Django]-Django β Clean permission table