Действительно утомительный выпуск сегодня с шаблонами Django. До недавнего времени я успешно использовал URL-теги без проблем. Я не могу понять это для моей жизни. В приведенном ниже коде. Если я делаю действительно ужасный способ сохранения URL-адреса как переменной, а затем помещаю его в элемент <a>
, у меня не возникает проблем, и он работает как обычно.
{% url 'app:post' post_id=recentpost.id as the_url %}
<a href="{{ the_url }}">I'm linking to {{recentpost.id }} {{the_url}}</a>
Вывод выше:
<a href="/post/18/">I'm linking to 18 /post/18/</a>
(Я сделал это таким образом, чтобы отладить происходящее - мне никогда не приходилось хранить URL-адрес как переменную, а затем вставлять его в <a>
раньше.)
Теперь, если я обычно делаю это в одном теге шаблона, я получаю ошибку NoReverseMatch:
<a href="{% url 'app:post' post_id=recentpost.id %}">TEST</a>
django.urls.exceptions.NoReverseMatch: Reverse for 'post' with keyword arguments '{'post_id': ''}' not found. 1 pattern(s) tried: ['post\\\\/(?P<post_id>[0-9]+)\\\\/$']
Что раздражает, так это то, что ниже шаблона есть идентичный тег {% url %}
, разрешающий тот же URL-адрес, но с другим идентификатором модели поста, единственное отличие состоит в том, что имя переменной «post», а не «latestpost»
В Исключении видно, что он передает пустую переменную в 'post_id' - или что latestpost.id = "" - Если я просто распечатываю переменную, номер идентификатора отображается нормально или если я сохраняю ее как переменную первое - работает нормально.
Я в растерянности. Haaaaaaalp!
EDIT:
{# This doesn't work either with same error #}
{% url 'app:post' recentpost.id %}
URL-путь:
path('post/<int:post_id>/', views.post, name='post')
Я использую ту же самую контекстную переменную сразу после тега <a>
и успешно обращаюсь к переменным.
Вот views.py:
def post(request, **kwargs):
blogpost = BlogPost.objects.get(pk=kwargs['post_id'])
#Make sure we don't populate our lists below with the current requested post
blogposts = BlogPost.objects.filter(project=None).exclude(id=kwargs['post_id']).order_by('-date_created')
recentposts = BlogPost.objects.exclude(id=kwargs['post_id']).order_by('-date_created')[:5]
blogposts = blogposts[0:10]
kwargs.update({'blogpost':blogpost})
kwargs.update({'blogpost_list':blogposts})
kwargs.update({'recentposts_list':recentposts})
return HttpResponse(render_to_response('public_frontend/blogpost.html', kwargs, RequestContext(request)))
def dev_index(request, **kwargs):
blogposts = BlogPost.objects.filter(project=None).order_by('-date_created')
recentpost = blogposts[0]
blogposts = blogposts[1:10]
kwargs.update({'recentpost':recentpost})
kwargs.update({'blogpost_list':blogposts})
return HttpResponse(render_to_response('public_frontend/dev_index.html', kwargs, RequestContext(request)))
dev_index
- это представление, которое отправляется в шаблон с ошибкой.
blog
Представление имеет ноль проблем, когда int ID передается в качестве аргумента и работает как обычно
Это проблема, которую я сузил:
Reverse for 'post' with keyword arguments '{'post_id': ''}' not found
Recentpost.id появляется как пустая переменная - когда это не так.
Работает здесь => {% url 'app:post' post_id=recentpost.id as the_url %}
Здесь не работает => {% url 'app:post' post_id=recentpost.id %}
=============================================== ==============================
Последние изменения:
Если я окружаю один и тот же тег в произвольном цикле for - он работает как положено.
{{recentpost}} <!-- prints "BlogPost Object (15)"
{{recentpost.id}} <!-- prints 15
{% for test in recentpost.name %}
<a href="{% url 'app:post' post_id=recentpost.id %}"></a>
{% endfor %}
Output: <a href="/post/15/"></a> (*n) number of characters in title
Также я получаю одинаковую ошибку для обоих:
{% url 'app:post' post_id='' %}
{% url 'app:post' post_id=recentpost.id %}
А при размещении в блоке with
:
{{recentpost}} <!-- prints "BlogPost Object (15)"
{{recentpost.id}} <!-- prints 15
{% with test=recentpost%}
<a href="{% url 'app:post' post_id=test.id %}"></a>
{% endwith %}
Output: NoReverseMatch Error -- Reverse for 'post' with keyword arguments '{'post_id': ''}' not found.
Также работает, если находится между тегами if
:
{% if recentpost%} <a href="{% url 'app:post' post_id=recentpost.id %}"></a>{% endif %} <!-- Works with no error and returns proper url
<a href="{% url 'app:post' post_id=recentpost.id %}"></a> <!-- Does not work and returns a NoReverseMatch 404 because the `recentpost` variable is `None`
Это точная ошибка - она выдаст ошибку 404 или NoReverseMatch для URL /post/
- она вернет URL, только если он /post/15/
- или любое целое число.
Проблема, похоже, связана с переменной контекста recentpost
Она работает в {{recentpost}}
печати - но как только я использую ее в теге url, она None
- как будто шаблон не имеет вовремя загрузил объект, чтобы использовать его в теге URL.
ДОПОЛНИТЕЛЬНЫЕ ДОКАЗАТЕЛЬСТВА:
<a href="{% url 'app:post' post_id=recentpost|default:'NONE' %}"></a>
Output: NoReverseMatch: Reverse for 'post' with keyword arguments '{'post_id': 'NONE'}' not found.
Это ожидаемая ошибка, поскольку /post/NONE/
вернет ошибку 404
Фактическим объектом является None или Null и по умолчанию используется пробел - если я переопределю значение по умолчанию с помощью |default='NONE'
, мы увидим, что проблема заключается в том, что переменная не существует в контексте внутри этого тега URL
Я также попытался передать контекстную переменную test_post='15'
в шаблон из представления, и у меня возникла та же проблема.
{{test_post}} <!-- output in template is 15
но
{% url 'app:post' post_id=test_post|default='NONE' %}
Output: NoReverseMatch: Reverse for 'post' with keyword arguments '{'post_id': 'NONE'}' not found.
Переменная определенно передается в шаблон - как и другие, но когда --ANY - переменная помещается в тег {%url%}
без нахождения в блоке for
или if
, это None
например даже если я сделаю:
{% url 'app:post' post_id=blogposts.0.id %} it's None
но в цикле blogposts
For
элементы не None
, и тег {%url%}
отлично работает с этим блоком цикла.