211 votes

Comment concaténer des chaînes de caractères dans les modèles django ?

Je veux concaténer une chaîne dans une balise de modèle Django, comme :

{% extend shop/shop_name/base.html %}

Ici shop_name est ma variable et je veux la concaténer avec le reste du chemin.

Supposons que j'ai shop_name=example.com et je veux que le résultat s'étende shop/example.com/base.html .

404voto

Steven Points 1556

A utiliser avec :

{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}

2 votes

J'étais totalement confus par cette réponse car elle utilise la balise include au lieu de la balise extend, mais apparemment ça fonctionne. Cependant, je recommanderais la réponse d'Ahsan car elle fonctionne également et est (à mon avis) sémantiquement plus correcte et suscite moins de confusion.

17 votes

Cela peut fonctionner mais ne doit pas être considéré comme une réponse générale pour concaténer des chaînes de caractères dans les modèles django. Voir stackoverflow.com/a/23783666/781695

0 votes

Comme le dit la documentation de Django, "Les chaînes de caractères qui peuvent être converties en nombres entiers seront additionnées et non concaténées". Ainsi, par exemple, si vous voulez concaténer les clés primaires des objets du modèle (ce qui peut être utile pour créer une clé de cache unique), cela ne fonctionne pas.

124voto

buffer Points 2261

N'utilisez pas add pour les chaînes de caractères, vous devez définir une balise personnalisée comme ceci :

Créer un fichier : <appname>\templatetags\<appname>_extras.py

from django import template

register = template.Library()

@register.filter
def addstr(arg1, arg2):
    """concatenate arg1 & arg2"""
    return str(arg1) + str(arg2)

et ensuite l'utiliser comme le dit @Steven

{% load <appname>_extras %}

{% with "shop/"|addstr:shop_name|addstr:"/base.html" as template %}
    {% include template %}
{% endwith %}

Raison de l'évitement add :

Selon le docs

Ce filtre premièrement essayer de convertir les deux valeurs en entiers... Les chaînes de caractères qui peuvent être converties en nombres entiers seront additionnées, non concaténés ...

Si les deux variables se trouvent être des entiers, le résultat serait inattendu.

0 votes

Cela ne devrait-il pas être @register.filter(name='addstr') ?

0 votes

Bien vu, j'ai changé le nom de la fonction en addstr

0 votes

On dirait qu'un seul entier est suffisant... Merci pour cela, cela m'aurait pris des siècles à comprendre !

16voto

Ahsan Points 3957

J'ai modifié la hiérarchie des dossiers

/boutique/nom_de_boutique/base.html A /nom_de_la_boutique/base.html

et alors le dessous fonctionnerait.

{% extends shop_name|add:"/shop/base.html"%} 

Maintenant, il est capable d'étendre la page base.html.

1 votes

Les autres réponses ne permettent pas d'utiliser la concaténation avec extends comme `extends doit être la première balise de modèle dans le modèle

3voto

Daniel Hepper Points 4992

Jetez un coup d'œil à la add filtre .

Edit : Vous pouvez enchaîner les filtres, donc vous pourriez faire "shop/"|add:shop_name|add:"/base.html" . Mais cela ne fonctionnera pas car c'est à la balise template d'évaluer les filtres dans les arguments, et extends ne le fait pas.

Je suppose que vous ne pouvez pas le faire dans les modèles.

0 votes

Cela ne va pas fonctionner. Je veux ajouter ma variable au milieu du chemin.

0 votes

Ajout d'un filtre qui ne fait que la somme et non la concaténation selon la documentation de django

0 votes

La documentation indique que "les chaînes de caractères qui peuvent être converties en nombres entiers seront additionnées". Les autres chaînes de caractères sont concaténées. Mais cela n'a pas vraiment d'importance de toute façon car vous ne pouvez pas utiliser le filtre :(

2voto

Paulo Scardine Points 17518

Dans la documentation :

Cette étiquette peut être utilisée de deux façons :

  • {% extends "base.html" %} (avec guillemets) utilise la valeur littérale "base.html" comme nom du modèle parent à étendre.
  • {% extends variable %} utilise la valeur de la variable. Si la variable a pour valeur une chaîne de caractères, Django utilisera cette chaîne comme nom du modèle parent. Si la variable a pour valeur un objet Modèle, Django utilisera cet objet comme modèle parent.

Il semble donc que vous ne pouvez pas utiliser un filtre pour manipuler l'argument. Dans la vue appelante, vous devez soit instancier le modèle ancêtre, soit créer une variable de type chaîne avec le chemin d'accès correct et le passer avec le contexte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X