Использование {% url ...%} против {{ ... }} в шаблонах Django

Я занимаюсь Djnago и для этого создавал блог. В процессе его создания я столкнулся с ошибкой при использовании следующего кода:

<a href="{% url 'blog_post' post.slug %}">
    {{ post.title }}
</a>

Во время учебы и других занятий нечто подобное работало бы нормально. Но теперь оно вызовет это исключение: NoReverseMatch.

Если я использую этот код, он будет работать просто отлично:

<a href="{{ post.slug }}">
    {{ post.title }}
</a>

При работе в разных проектах первый способ сработал бы отлично, но в этот раз - нет.

Мой вопрос - почему?

Вот код в моих урлах и на моих вьюшках. Возможно, ошибка здесь, а не где-то еще.

Если кто-нибудь может объяснить, почему это происходит, или где я ошибаюсь, это будет очень признательно

урлы:

from django.urls import path

from . import views

app_name = 'blog'

urlpatterns = [
    path('', views.blog_index, name='blog_index'),
    path('<slug:post_slug>/', views.blog_post, name='blog_post'),
]

просмотров:

from django.shortcuts import render
from .models import Post

# Create your views here.
def blog_index(request):
    posts = Post.objects.order_by('- 
    created').filter(published=True)
    data = {
        'posts': posts
    }
    return render(request, 'blog/post_list.html', data)

def blog_post(request, post_slug):
    post = Post.objects.get(slug=post_slug)
    data = {
        'post': post
    }
    return render(request, 'blog/post_detail.html', data)

попробуйте это. Ваша проблема в том, что у вас есть пространство имен в вашем urls.py, тогда в вашем href вы должны добавить это namespace('blog').

<a href="{% url 'blog:blog_post' post.slug %}">
    {{ post.title }}
</a>

this

 <a href="{{ post.slug }}">
    {{ post.title }}
</a>

приведенный выше код работал, потому что вы находитесь на главной странице, и когда вы добавляете this(href="{{ post.slug }}" в тег a), он просто вызывает текущий url +"/<'slug:post_slug/', а это правильный url.
чтобы узнать об этом, обратитесь к этому https://docs.djangoproject.com/en/3.2/topics/http/urls/#url-namespaces.

В таких случаях следует использовать: https://docs.djangoproject.com/en/3.2/ref/models/instances/#get-absolute-url. Чем меньше логики в шаблонах, тем лучше для приложения. Трудно писать тесты на логику, которая содержится в шаблонах.

Вам следует добавить метод к вашей модели:

from django.urls import reverse

class Post()
    ...
    def get_absolute_url(self):
        return reverse('blog:blog_post', kwargs={'post_slug' : self.slug})

и затем в шаблоне используйте:

{{ post.get_absolute_url }}

Из документации:

Логика здесь такова: если вы изменяете структуру URL ваших объектов, даже для чего-то небольшого, например, исправления орфографической ошибки, вы не хотите отслеживать каждое место, где может быть создан URL. Укажите его один раз, в get_absolute_url(), и пусть весь ваш остальной код вызывает это одно место.

.
Вернуться на верх