diff --git a/django/utils/html.py b/django/utils/html.py
index 25605be..ec7b28d 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -87,8 +87,8 @@ def format_html(format_string, *args, **kwargs):
 
 def format_html_join(sep, format_string, args_generator):
     """
-    A wrapper format_html, for the common case of a group of arguments that need
-    to be formatted using the same format string, and then joined using
+    A wrapper of format_html, for the common case of a group of arguments that
+    need to be formatted using the same format string, and then joined using
     'sep'. 'sep' is also passed through conditional_escape.
 
     'args_generator' should be an iterator that returns the sequence of 'args'
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index ee04d77..a862d55 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -449,17 +449,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):
@@ -500,12 +508,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'
 
@@ -817,19 +830,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.
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 20192ed..2dc007f 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -541,6 +541,20 @@ escaping HTML.
     through :func:`conditional_escape` which (ultimately) calls
     :func:`~django.utils.encoding.force_text` on the values.
 
+.. function:: format_html_join(sep, format_string, args_generator)
+
+    A wrapper of :func:`format_html`, for the common case of a group of
+    arguments that need to be formatted using the same format string, and then
+    joined using ``sep``. ``sep`` is also passed through
+    :func:`conditional_escape`.
+
+    ``args_generator`` should be an iterator that returns the sequence of
+    ``args`` that will be passed to :func:`format_html`. For example::
+
+        format_html_join('\n', "<li>{0} {1}</li>", ((u.first_name, u.last_name)
+                                                    for u in users))
+
+
 .. function:: strip_tags(value)
 
     Removes anything that looks like an html tag from the string, that is
