Reputation: 13515
I have this admin.py
class LawyerAdmin(admin.ModelAdmin):
fieldsets = [
('Name', {'fields': ['last', 'first', 'firm_name', 'firm_url', 'school', 'year_graduated']}),
]
list_display = ('last', 'first', 'school', 'year_graduated', 'firm_name', 'firm_url')
list_filter = ['school', 'year_graduated']
search_fields = ['last', 'school', 'firm_name']
and I want to make "firm_url" fields clickable with each of the url listed in the field. How can I do this? Thank you.
Upvotes: 89
Views: 74482
Reputation: 7460
Use the format_html
utility. This will escape any html from parameters and mark the string as safe to use in templates. The allow_tags
method attribute has been deprecated in Django 1.9.
from django.utils.html import format_html
from django.contrib import admin
class LawyerAdmin(admin.ModelAdmin):
list_display = ['show_firm_url', ...]
...
@admin.display(description="Firm URL")
def show_firm_url(self, obj):
return format_html("<a href='{url}'>{url}</a>", url=obj.firm_url)
Now your admin users are safe even in the case of:
firm_url == 'http://a.aa/<script>eval(...);</script>'
See the documentation for more info.
Upvotes: 158
Reputation: 8011
Here is a solution that makes it easy to make all URL fields clickable:
def format_url(url):
return format_html("<a href='{url}'>{url}</a>", url=url)
# Based on https://stackoverflow.com/a/53092940/2725810
def linkify(field):
def _linkify(obj):
linked_obj = getattr(obj, field.name)
return format_url(linked_obj)
_linkify.short_description = field.name # Sets column name
return _linkify
def linkified_list_display(model):
result = []
for f in model._meta.fields:
if f.__class__ is URLField:
result.append(linkify(field=f))
continue
result.append(f.name)
return result
class MyModelAdmin(admin.ModelAdmin):
list_display = linkified_list_display(MyModel)
Upvotes: 0
Reputation: 11
its more easy..
#in your admin.py add
from django.utils.html import format_html
##Code:
#url_file = "your field contain de url of file" example: http://127.0.0.1:8000 /backdown/respaldo.zip
list_display = ["url_file","download_content"]
#Link download
def download_content(self, obj):
return format_html('<a href="%s">%s</a>' % (obj.url_file, "Download"))
download_content.allow_tags = True
download_content.short_description = "Download Content File"
##in your html see like this..
<a href="http://127.0.0.1:8000/backdown/respaldo.zip">http://127.0.0.1:8000/backdown/respaldo.zip</a>
Upvotes: 1
Reputation: 130
You can handle it in the model if you prefer:
In models.py :
class Foo(models.Model):
...
def full_url(self):
url = 'http://google.com'
from django.utils.html import format_html
return format_html("<a href='%s'>%s</a>" % (url, url))
admin.py:
list_display = ('full_url', ... )
Upvotes: 5
Reputation: 161
But it overrides the text display specified in my models and displays "show firm url" on the head of the column
You can change it by assigning short_description property:
show_firm_url.short_description = "Firm URL"
Upvotes: 5
Reputation: 599490
Define a custom method in your LawyerAdmin class that returns the link as HTML:
def show_firm_url(self, obj):
return '<a href="%s">%s</a>' % (obj.firm_url, obj.firm_url)
show_firm_url.allow_tags = True
See the documentation.
Upvotes: 70