Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use allow_tags in django 2.0 admin?

Tags:

python

django

Support for the allow_tags attribute on ModelAdmin methods is removed.

like image 410
ospider Avatar asked Dec 23 '17 15:12

ospider


People also ask

How do I use Django admin?

To login to the site, open the /admin URL (e.g. http://127.0.0.1:8000/admin ) and enter your new superuser userid and password credentials (you'll be redirected to the login page, and then back to the /admin URL after you've entered your details).

What is admin Modeladmin in Django?

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.

What is Prepopulated_fields in Django admin?

The attribute prepopulated_fields tells the admin application to automatically fill the field slug - in this case with the text entered into the name field.

Where is admin site urls in Django?

If you open a Django project's urls.py file, in the urlpatterns variable you'll see the line path('admin/', admin. site. urls) . This last path definition tells Django to enable the admin site app on the /admin/ url directory (e.g. http://127.0.0.1:8000/admin/ ).


4 Answers

Just found the answer, use mark_safe function.

In old code, you may use:

def image_(self, obj):     return '<image src="%s" />' % obj.image image_.allow_tags = True 

In new code, you should use:

from django.utils.safestring import mark_safe def image(self, obj):     return mark_safe('<image src="%s" />' % obj.image) 
like image 176
ospider Avatar answered Sep 26 '22 12:09

ospider


Additionaly to the other answers you can use the mark_safe function as decorator:

from django.utils.safestring import mark_safe  @mark_safe def icon_pw(self, obj):     return f'<img src="{obj.icon.url}" />' if obj.icon else '' icon_pw.short_description = 'Icon' icon_pw.allow_tags = True 

This is the easy way to upgrade your old Django admin code to 2.0.

like image 38
Dmitry Akinin Avatar answered Sep 23 '22 12:09

Dmitry Akinin


If you have your code in admin.py you can overwrite adding only mark_safe function, like the example below:

from django.utils.safestring import mark_safe

def get_image_tag(self):
        if self.picture:
            return mark_safe('<img src="%s" width="60" height="75" />' % self.picture.url)
        else:
            return ' '
get_image_tag.short_description = 'Photo'
#get_image_tag.allow_tags = True #redundant
get_image_tag.admin_order_field = 'name'

This code was tested in Django 2.0.2 and Python 3.6.4.

like image 43
Emilio Ferreyra Avatar answered Sep 22 '22 12:09

Emilio Ferreyra


TL;DR: You should probably use format_html() rather than mark_safe, as recommended by other answers.

The way other answers recommend to use mark_safe will just mark the entire resulting string as safe HTML. IOW, you're telling Django "This is valid and safe HTML, I have ensured any needed escaping has happened". Except that the other answers do not actually do the required escaping.

Consider the following (imperfect) approach from another answer:

from django.utils.safestring import mark_safe
def image(self, obj):
    return mark_safe('<image src="%s" />' % obj.image)

If obj.image now contains a ", or worse, is user input and contains an XSS attack, this will break the resulting HTML.

To prevent this, all data that is interpolated into such HTML snippets should be individually escaped beforehand. Fortunately there is the html_format() function which does both interpolation and the needed escaping. With that, the above example would become:

from django.utils.html import format_html
def image(self, obj):
    return format_html('<image src="{}" />', obj.image)

Note that his uses {} format strings rather than %s, since format_html() is based on str.format(), which uses that style.

like image 31
Matthijs Kooijman Avatar answered Sep 26 '22 12:09

Matthijs Kooijman