URL-тег Django: получение NoReverseMatch для идентификатора модели, даже если он существует - PullRequest
0 голосов
/ 03 мая 2018

Действительно утомительный выпуск сегодня с шаблонами 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%} отлично работает с этим блоком цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...