我有一个带有Artist和Track类的模型,当Track的title字段有大括号时,我得到一个KeyError异常。 (例如,曲目标题“Beat It {Freestyle}”)。看起来django_tables2正在将我的Track标题字段值传递给string.format()。如何在django_tables2中阻止它?
class Artist (models.Model):
name = models.CharField(max_length=100)
slug = AutoSlugField(populate_from='name', unique=True, editable=True, slugify=custom_slugify)
class Track (models.Model):
artist = models.ForeignKey(Artist, blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Artist")
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, verbose_name="Submitted by", default=1)
title = models.CharField(max_length=100, verbose_name="Title")
timestamp = models.DateTimeField(default=timezone.now)
class TrackTable(tables.Table):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
self.artistlink = kwargs.pop('artistlink', None)
super(TrackTable, self).__init__(*args, **kwargs)
def render_artist(self, value):
if self.artistlink == True:
return format_html('<a href="/music/by/{}">{}</a>', value.slug, value)
else:
return value
def render_user(self, value):
return format_html('<a href="/users/{}">{}</a>', value, value)
download = DownloadColumn(empty_values=(), orderable=False)
track_id = tables.CheckBoxColumn(accessor="pk",
attrs = {"th__input": {"id": "checkAll"}},
orderable=False)
class Meta:
model = Track
attrs = {"class": "table table-bordered table-condensed table-striped", "id": "track-table",}
fields = ('track_id', 'artist', 'title', 'user', 'download')
def profile_detail(request, slug=None):
alpha_list = ['0-9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
playlist_list = Playlist.objects.filter(user=request.user.id)
track_list = Track.objects.filter(artist__slug=slug)
ltr = slug[0].upper()
artist = get_object_or_404(Artist, slug=slug)
table = TrackTable(track_list, user=request.user, artistlink=False)
RequestConfig(request, paginate={"per_page": 15}).configure(table)
context = {
"playlist_list": playlist_list,
"track_list": track_list,
"table": table,
"alpha_list": alpha_list,
"artist": artist,
}
return render(request, "profile_detail.html", context)
<form method='POST' id="add-track-form" action='{% url "playlists:playlist_addtrack" %}'>{% csrf_token %}
...
{% render_table table "django_tables2/bootstrap3.html" %}
...
</form>
% load querystring from django_tables2 %}
{% load trans blocktrans from i18n %}
{% load bootstrap3 %}
{% if table.page %}
<div class="table-responsive">
{% endif %}
{% block table %}
<table{% if table.attrs %} {{ table.attrs.as_html }}{% endif %}>
{% block table.thead %}
<thead>
<tr>
{% for column in table.columns %}
{% if column.orderable %}
<th {{ column.attrs.th.as_html }}><a href="{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}">{{ column.header }}</a></th>
{% else %}
<th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
{% endblock table.thead %}
{% block table.tbody %}
<tbody>
{% for row in table.page.object_list|default:table.rows %} {# support pagination #}
{% block table.tbody.row %}
<tr class="{% cycle "odd" "even" %}">
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{{ cell }}</td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
</tbody>
{% endblock table.tbody %}
{% block table.tfoot %}
<tfoot></tfoot>
{% endblock table.tfoot %}
</table>
</div> <!-- table-responsive -->
{% endblock table %}
回溯:
Template error:
In template /Users/will/bpmdata/bpmdb/templates/django_tables2/bootstrap3.html, error at line 29
Freestyle 19 : {% endif %}
20 : {% endfor %}
21 : </tr>
22 : </thead>
23 : {% endblock table.thead %}
24 : {% block table.tbody %}
25 : <tbody>
26 : {% for row in table.page.object_list|default:table.rows %} {# support pagination #}
27 : {% block table.tbody.row %}
28 : <tr class="{% cycle "odd" "even" %}">
29 : {% for column, cell in row.items %}
30 : <td {{ column.attrs.td.as_html }}>{{ cell }}</td>
31 : {% endfor %}
32 : </tr>
33 : {% endblock table.tbody.row %}
34 : {% empty %}
35 : {% if table.empty_text %}
36 : {% block table.tbody.empty_text %}
37 : <tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
38 : {% endblock table.tbody.empty_text %}
39 : {% endif %}
Traceback:
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
41. response = get_response(request)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/core/handlers/base.py" in _legacy_get_response
249. response = self._get_response(request)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
187. response = self.process_exception_by_middleware(e, request)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/will/bpmdata/bpmdb/profiles/views.py" in profile_detail
136. return render(request, "profile_detail.html", context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/shortcuts.py" in render
30. content = loader.render_to_string(template_name, context, request, using=using)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader.py" in render_to_string
68. return template.render(context, request)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/backends/django.py" in render
66. return self.template.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
207. return self._render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader_tags.py" in render
177. return compiled_parent._render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader_tags.py" in render
72. result = block.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/defaulttags.py" in render
322. return nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/templatetags/django_tables2.py" in render
154. return template.render(context.flatten())
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/backends/django.py" in render
66. return self.template.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
207. return self._render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in _render
199. return self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader_tags.py" in render
63. result = self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader_tags.py" in render
63. result = self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/defaulttags.py" in render
216. nodelist.append(node.render_annotated(context))
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/loader_tags.py" in render
63. result = self.nodelist.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render
990. bit = node.render_annotated(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/base.py" in render_annotated
957. return self.render(context)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/template/defaulttags.py" in render
172. values = list(values)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/rows.py" in items
229. yield (column, self.get_cell(column.name))
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/rows.py" in get_cell
180. default=self.table.columns[name].default
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/rows.py" in _get_and_render_with
155. return render_func(bound_column, value)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/rows.py" in _call_render
189. self._optional_cell_arguments(bound_column, value)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django_tables2/utils.py" in call_with_appropriate
511. return fn(**kwargs)
File "/Users/will/bpmdata/bpmdb/profiles/tables.py" in render
42. return format_html(referral_url, artist=artist1, title=record.title)
File "/Users/will/.virtualenvs/bpmdb/lib/python3.5/site-packages/django/utils/html.py" in format_html
100. return mark_safe(format_string.format(*args_safe, **kwargs_safe))
Exception Type: KeyError at /music/by/michael-jackson/
Exception Value: 'Freestyle'
答案 0 :(得分:2)
考虑到调用str.format
时字符串中的花括号无法以静默方式传递,除非您控制格式化的完成方式(您可以在此处),您可以将花括号替换为其他字符,例如在预期((..))
时,可以使用双str.format
或加倍大括号;然而后者更脆弱,因为字段值取决于稍后调用str.format
:
>>> '{{Freestyle}}'.format()
'{Freestyle}'