diff options
| author | Tim Graham <timograham@gmail.com> | 2013-01-25 06:53:40 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2013-01-25 06:56:38 -0500 |
| commit | 42fcfcaa529dac1fe3066797d7e4ab7aa6f6cdf3 (patch) | |
| tree | 26266b7080f945895af14beb027f352cc184fa63 /docs/ref/contrib/admin | |
| parent | d571894fc09b34b8b43cb8f1790c743a47679851 (diff) | |
[1.5.x] Fixed #19577 - Added HTML escaping to admin examples.
Thanks foo@ for the report and Florian Apolloner for the review.
Backport of eafc036476 from master
Diffstat (limited to 'docs/ref/contrib/admin')
| -rw-r--r-- | docs/ref/contrib/admin/index.txt | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 27ecdaa9e5..757b387d78 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -451,17 +451,25 @@ subclass:: * If the string given is a method of the model, ``ModelAdmin`` or a callable, Django will HTML-escape the output by default. If you'd rather not escape the output of the method, give the method an - ``allow_tags`` attribute whose value is ``True``. + ``allow_tags`` attribute whose value is ``True``. However, to avoid an + XSS vulnerability, you should use :func:`~django.utils.html.format_html` + to escape user-provided inputs. Here's a full example model:: + from django.utils.html import format_html + class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_name(self): - return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name) + return format_html('<span style="color: #{0};">{1} {2}</span>', + self.color_code, + self.first_name, + self.last_name) + colored_name.allow_tags = True class PersonAdmin(admin.ModelAdmin): @@ -502,12 +510,17 @@ subclass:: For example:: + from django.utils.html import format_html + class Person(models.Model): first_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_first_name(self): - return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name) + return format_html('<span style="color: #{0};">{1}</span>', + self.color_code, + self.first_name) + colored_first_name.allow_tags = True colored_first_name.admin_order_field = 'first_name' @@ -833,19 +846,27 @@ subclass:: the admin interface to provide feedback on the status of the objects being edited, for example:: + from django.utils.html import format_html_join + from django.utils.safestring import mark_safe + class PersonAdmin(ModelAdmin): readonly_fields = ('address_report',) def address_report(self, instance): - return ", ".join(instance.get_full_address()) or \ - "<span class='errors'>I can't determine this address.</span>" + # assuming get_full_address() returns a list of strings + # for each line of the address and you want to separate each + # line by a linebreak + return format_html_join( + mark_safe('<br/>'), + '{0}', + ((line,) for line in instance.get_full_address()), + ) or "<span class='errors'>I can't determine this address.</span>" # short_description functions like a model field's verbose_name address_report.short_description = "Address" # in this example, we have used HTML tags in the output address_report.allow_tags = True - .. attribute:: ModelAdmin.save_as Set ``save_as`` to enable a "save as" feature on admin change forms. |
