Câu trả lời:
Dùng với:
{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}
shop_name
, vì vậy nó nguy hiểm.
shop_name
trước khi chuyển nó sang ngữ cảnh trong một khung nhìn, get_context_data
hãy chắc chắn rằng nó được dịch bằng cách sử dụng ugettext
thay vì ugettext_lazy
.
Không sử dụng add
cho chuỗi, bạn nên xác định một thẻ tùy chỉnh như thế này:
Tạo một tệp: <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)
và sau đó sử dụng nó như @Steven nói
{% load <appname>_extras %}
{% with "shop/"|addstr:shop_name|addstr:"/base.html" as template %}
{% include template %}
{% endwith %}
Lý do để tránh add
:
Theo các tài liệu
Bộ lọc này trước tiên sẽ cố gắng ép buộc cả hai giá trị cho số nguyên ... Các chuỗi có thể được ép buộc thành số nguyên sẽ được tính tổng, không được nối ...
Nếu cả hai biến là số nguyên, kết quả sẽ không như mong đợi.
add
" một mình chỉ không sử dụng str()
ở vị trí đầu tiên và không làm việc ở tất cả đối với tôi trong khi giải pháp của bạn hoạt động hoàn hảo
{% load <appname>_extras %}
Tham khảo Chuỗi liên kết trong Mẫu Django :
Đối với các phiên bản trước của Django:
{{ "Mary had a little"|stringformat:"s lamb." }}
"Mary có một con cừu nhỏ."
Khác:
{{ "Mary had a little"|add:" lamb." }}
"Mary có một con cừu nhỏ."
Có một cái nhìn vào add
bộ lọc .
Chỉnh sửa: Bạn có thể xâu chuỗi các bộ lọc, vì vậy bạn có thể làm "shop/"|add:shop_name|add:"/base.html"
. Nhưng điều đó sẽ không hoạt động vì nó phụ thuộc vào thẻ mẫu để đánh giá các bộ lọc trong các đối số và mở rộng thì không.
Tôi đoán bạn không thể làm điều này trong các mẫu.
Từ các tài liệu:
Thẻ này có thể được sử dụng theo hai cách:
{% extends "base.html" %}
(có dấu ngoặc kép) sử dụng giá trị bằng chữ "base.html" làm tên của mẫu chính để mở rộng.{% extends variable %}
sử dụng giá trị của biến. Nếu biến ước tính thành một chuỗi, Django sẽ sử dụng chuỗi đó làm tên của mẫu mẹ. Nếu biến ước tính thành một đối tượng Mẫu, Django sẽ sử dụng đối tượng đó làm mẫu chính.Vì vậy, có vẻ như bạn không thể sử dụng bộ lọc để thao tác đối số. Trong chế độ xem cuộc gọi, bạn phải khởi tạo mẫu tổ tiên hoặc tạo một biến chuỗi với đường dẫn chính xác và truyền nó với ngữ cảnh.
Câu trả lời của @ lỗi về cơ bản là đúng, bạn nên sử dụng thẻ mẫu cho việc này. Tuy nhiên, tôi thích một thẻ mẫu chung chung hơn một chút mà tôi có thể sử dụng để thực hiện bất kỳ loại hoạt động nào tương tự như sau:
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 ''
và sau đó bạn có thể sử dụng nó như thế này trong mẫu của bạn:
{% captureas template %}shop/{{ shop_name }}/base.html{% endcaptureas %}
{% include template %}
Như nhận xét đề cập, thẻ mẫu này đặc biệt hữu ích cho thông tin có thể lặp lại trong toàn bộ mẫu nhưng yêu cầu logic và những thứ khác sẽ làm hỏng mẫu của bạn hoặc trong trường hợp bạn muốn sử dụng lại dữ liệu được truyền giữa các mẫu thông qua các khối:
{% captureas meta_title %}{% spaceless %}{% block meta_title %}
{% if self.title %}{{ self.title }}{% endif %}
{% endblock %}{% endspaceless %} - DEFAULT WEBSITE NAME
{% endcaptureas %}
và sau đó:
<title>{{ meta_title }}</title>
<meta property="og:title" content="{{ meta_title }}" />
<meta itemprop="name" content="{{ meta_title }}">
<meta name="twitter:title" content="{{ meta_title }}">
Tín dụng cho thẻ captureas là do tại đây: https://www.djangosnippets.org/snippets/545/
Tôi thấy làm việc với các {% with %}
thẻ khá rắc rối. Thay vào đó tôi đã tạo thẻ mẫu sau, sẽ hoạt động trên chuỗi và số nguyên.
from django import template
register = template.Library()
@register.filter
def concat_string(value_1, value_2):
return str(value_1) + str(value_2)
Sau đó tải thẻ mẫu trong mẫu của bạn ở đầu bằng cách sử dụng như sau:
{% load concat_string %}
Sau đó, bạn có thể sử dụng nó theo cách sau:
<a href="{{ SOME_DETAIL_URL|concat_string:object.pk }}" target="_blank">123</a>
Cá nhân tôi thấy điều này sẽ sạch hơn rất nhiều khi làm việc.
Bạn không thể thực hiện thao tác biến trong các mẫu django. Bạn có hai tùy chọn, hoặc viết thẻ mẫu của riêng bạn hoặc thực hiện điều này trong chế độ xem,
extends
không có cơ sở cho việc này. Hoặc đặt toàn bộ đường dẫn mẫu vào một biến bối cảnh và sử dụng nó hoặc sao chép thẻ mẫu tồn tại và sửa đổi nó một cách thích hợp.
Và nhiều kết nối:
from django import template
register = template.Library()
@register.simple_tag
def concat_all(*args):
"""concatenate all args"""
return ''.join(map(str, args))
Và trong Mẫu:
{% concat_all 'x' 'y' another_var as string_result %}
concatenated string: {{ string_result }}