Использование {% 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(), и пусть весь ваш остальной код вызывает это одно место.
.