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

Je veux concaténer une chaîne dans la balise de modèle django comme

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

Ici shop_name est ma variable et je veux concaténer ceci avec le reste du chemin.
Supposons que j'ai shop_name=example.com

Et je veux que le résultat s'étend shop/example.com/base.html

161
demandé sur JMax 2010-12-08 12:58:14

10 réponses

Utiliser avec:

{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}
327
répondu Steven 2010-12-24 07:20:21

Ne pas utiliser add pour les chaînes, 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 @ Steven dit

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

Raison d'éviter add

Selon la docs

Ce filtre va d'abord essayer de forcer les deux valeurs en entiers... Les chaînes qui peuvent être contraintes à des entiers seront additionnées, Pas concaténées ...

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

78
répondu user 2015-12-21 06:28:46

J'ai changé la hiérarchie des dossiers

/ boutique / shop_name / base.html À /shop_name/shop/base.html

Et puis ci-dessous fonctionnerait.

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

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

10
répondu Ahsan 2013-04-10 11:47:29

À partir des documents:

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

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

Il semble donc que vous ne pouvez pas utiliser de filtre pour manipuler l'argument. Dans la vue appelant, vous devez instancier le modèle ancêtre ou créer une variable de chaîne avec le chemin correct et le transmettre avec le contexte.

2
répondu Paulo Scardine 2012-03-03 19:55:31

Jetez un oeil à la add filtre .

Edit: vous pouvez enchaîner les filtres, de sorte que vous pouvez faire "shop/"|add:shop_name|add:"/base.html". Mais cela ne fonctionnera pas car il appartient à 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.

2
répondu Daniel Hepper 2018-09-10 13:10:17

La réponse de

@error est fondamentalement juste, vous devriez utiliser une balise de modèle pour cela. Cependant, je préfère une balise de modèle légèrement plus générique que je peux utiliser pour effectuer n'importe quel type d'opérations similaires à ceci:

from django import template
register = template.Library()


@register.tag(name='captureas')
def do_captureas(parser, token):
    """
    Capture content for re-use throughout a template.
    particularly handy for use within social meta fields 
    that are virtually identical. 
    """
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("'captureas' node requires a variable name.")
    nodelist = parser.parse(('endcaptureas',))
    parser.delete_first_token()
    return CaptureasNode(nodelist, args)


class CaptureasNode(template.Node):
    def __init__(self, nodelist, varname):
        self.nodelist = nodelist
        self.varname = varname

    def render(self, context):
        output = self.nodelist.render(context)
        context[self.varname] = output
        return ''

Et puis vous pouvez l'utiliser comme ceci dans votre modèle:

{% captureas template %}shop/{{ shop_name }}/base.html{% endcaptureas %}
{% include template %}

Comme le mentionne le commentaire, cette balise de modèle est particulièrement utile pour les informations répétables dans un modèle, mais nécessite une logique et d'autres choses qui vont gonfler vos modèles, ou dans les cas où vous souhaitez réutiliser des données transmises entre les modèles via des blocs:

{% captureas meta_title %}{% spaceless %}{% block meta_title %}
    {% if self.title %}{{ self.title }}{% endif %}
    {% endblock %}{% endspaceless %} - DEFAULT WEBSITE NAME
{% endcaptureas %}

Puis:

<title>{{ meta_title }}</title>
<meta property="og:title" content="{{ meta_title }}" />
<meta itemprop="name" content="{{ meta_title }}">
<meta name="twitter:title" content="{{ meta_title }}">

Le crédit pour la balise captureas est dû ici: https://www.djangosnippets.org/snippets/545/

1
répondu K3TH3R 2016-04-22 03:15:02

J'ai trouvé que travailler avec la balise {% with %} était assez compliqué. Au lieu de cela, j'ai créé la balise de modèle suivante, qui devrait fonctionner sur les chaînes et les entiers.

from django import template

register = template.Library()


@register.filter
def concat_string(value_1, value_2):
    return str(value_1) + str(value_2)

Ensuite, chargez la balise de modèle dans votre modèle en haut en utilisant ce qui suit:

{% load concat_string %}

Vous pouvez ensuite l'utiliser de la manière suivante:

<a href="{{ SOME_DETAIL_URL|concat_string:object.pk }}" target="_blank">123</a>

Personnellement, j'ai trouvé que c'était beaucoup plus propre à travailler.

1
répondu Bono 2017-08-02 12:05:44

Reportez-vous à concaténation de chaînes dans les modèles Django:

  1. Pour les versions antérieures de Django:

    {{"Mary avait un peu| / stringformat:" s lamb." }}

"Marie avait un petit agneau."

  1. Autre:

    {{ "Marie avait un peu| / ajouter:" agneau." }}

"Marie avait un petit agneau."

1
répondu bing 2018-03-05 03:08:45

Vous ne pouvez pas faire de manipulation de variables dans les modèles django. Vous avez deux options, soit écrire votre propre tag template, soit le faire dans view,

0
répondu damir 2010-12-08 10:05:22

extends n'a aucune facilité pour cela. Placez le chemin du modèle entier dans une variable de contexte et utilisez-le, ou copiez la balise de modèle exist et modifiez-la de manière appropriée.

0
répondu Ignacio Vazquez-Abrams 2010-12-08 11:20:58