Skip to content

Commit 2677b0d

Browse files
committed
Fix custom filters
1 parent 470a135 commit 2677b0d

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

docs/third-party/webdev/django/templates.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -791,15 +791,18 @@ Lo que nos quedaría es utilizar el filtro creado en alguna plantilla:
791791
792792
Hay ocasiones en las que nos interesa implementar un filtro que devuelva código HTML. En principio lo haríamos de la misma forma que se ha visto anteriormente devolviendo una cadena de texto con el código HTML correspondiente.
793793
794-
Pero hay que tener en cuenta que, por razones de seguridad, Django *escapa* dicho HTML y no lo veremos renderizado en la plantilla final. Es por ello que debemos hacer uso de la función [`mark_safe`](https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.safestring.mark_safe).
794+
Pero hay que tener en cuenta ciertos aspectos de seguridad:
795+
796+
1. Si el código HTML que vamos a devolver desde el filtro contiene potencial información proveniente del usuario (vía formulario por ejemplo), es altamente recomendable utilizar la función [`format_html`](https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.html.format_html) que se encarga de escapar sus argumentos. Evitaríamos por ejemplo ataques XSS.
797+
2. Si el código HTML que vamos a devolver contiene información confiable, necesitamos «marcarlo como seguro» para que Django realmente lo renderice en la plantilla final. Para ello haríamos uso de la función [`mark_safe`](https://docs.djangoproject.com/en/stable/ref/utils/#django.utils.safestring.mark_safe).
795798
796799
Un <span class="example">ejemplo:material-flash:</span> podría ser mostrar un determinado «post» con un formato HTML destacado:
797800
798801
=== "Filtro"
799802
800803
```python title="posts/templatetags/post_extras.py" hl_lines="2 13"
801804
from django import template
802-
from django.utils.html import mark_safe#(1)!
805+
from django.utils.html import format_html#(1)!
803806
804807
805808
from posts.models import Post
@@ -809,13 +812,12 @@ Un <span class="example">ejemplo:material-flash:</span> podría ser mostrar un d
809812
810813
@register.filter
811814
def post_link(post: Post) -> str:
812-
html = f'<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>'
813-
return mark_safe(html)#(2)!
815+
return format_html('<a href="{}">{}</a>', post.get_absolute_url, post.title)#(2)!
814816
```
815817
{ .annotate }
816818
817-
1. Importamos la función necesaria.
818-
2. Marcamos como seguro el código HTML a devolver.
819+
1. Importamos la función `format_html` necesaria para «securizar» nuestro código.
820+
2. Interpolamos los atributos necesarios del «post».
819821
820822
=== "Plantilla"
821823

0 commit comments

Comments
 (0)