Нужна помощь в исправлении ошибки Django 404, не находит статическую страницу с помощью URLConf
Мой Django-проект - это сайт с одним приложением, где на главной странице отображаются статьи/посты из моей базы данных, а также будут страницы для тем тегов и архивов за год/месяц. Все остальные страницы - это статические страницы для фото- и видеогалерей, а также страница о сайте - они вообще не используют базу данных.
Я пытаюсь заставить одну из статических страниц отображаться, но постоянно сталкиваюсь с 404 ошибкой (примечание: я заменил имя приложения на «<app_name>»):
No article found matching the query
Request Method: GET
Request URL: http://127.0.0.1:8000/illustrations
Raised by: <app_name>.views.ArticleDetailView
Using the URLconf defined in website.urls, Django tried these URL patterns, in this order:
admin
[name='home']
<slug:slug> [name='article_detail']
The current path, illustrations, matched the last one.
На главной странице все статьи отображаются в ListView, а отдельные статьи можно щелкнуть, чтобы просмотреть их в DetailView с указанным slug в качестве URL. Файл «illustrations» - это отдельная статическая HTML-страница, которую я буду использовать и которая не имеет никакого отношения ни к базе данных, ни к представлениям List или Detail.
Я не могу понять, нужно ли мне сделать домашнюю страницу отдельным приложением, или мне просто нужно изменить мои файлы URLs/Views. (Я изучаю Django и Python, так что я определенно учусь по ходу дела.)
Вот views.py:
from django.shortcuts import render
from django.views import generic
from .models import Article
from django.http import JsonResponse # Ignore for now, I just put this here for when I work on making a JSON feed
class ArticleListView(generic.ListView):
model = Article
paginate_by = 6
template_name = "index.html"
class ArticleDetailView(generic.DetailView):
model = Article
template_name = "article.html"
def illustrations(request):
return render(request, "illustrations.html")
urls.py (проект):
from django.contrib import admin
from django.conf import settings
from django.urls import path, include
from django.conf.urls.static import static
urlpatterns = [
path('admin', admin.site.urls),
path("", include("<app_name>.urls")),
]
if settings.DEBUG: # new
urlpatterns + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urls.py (app):
from django.urls import path
from . import views
from django.conf.urls.static import static # Not sure if needed
from django.views.generic import TemplateView
from .views import ArticleListView, ArticleDetailView
# For setup info, see https://learndjango.com/tutorials/django-file-and-image-uploads-tutorial
urlpatterns = [
path("", ArticleListView.as_view(), name="home"), # This is index.html,
path("<slug:slug>", ArticleDetailView.as_view(), name="article_detail"),
path("illustrations", views.illustrations, name="illustrations"),
]
Это происходит потому, что Django не знает, что «illustrations» не является slug для вашей модели. Тип slug
будет соответствовать любому буквенно-цифровому символу, дефису или подчеркиванию (regex [A-Za-z0-9-_]
.
Django всегда переходит к первому совпавшему шаблону url, поэтому он никогда не достигнет вашего предполагаемого url для «illustrations».
Варианты исправления:
1. Переместите шаблон url «иллюстрации» выше ArticleDetailView
# <app>.urls.py
urlpatterns = [
path("", ArticleListView.as_view(), name="home"), # This is index.html,
path("illustrations", views.illustrations, name="illustrations"),
path("<slug:slug>", ArticleDetailView.as_view(), name="article_detail"),
]
Примечание: Вы также можете добавить большинство illustrations
к вашему project.urls
, поскольку оно будет оцениваться первым.
2. Префикс URL DetailView, чтобы «иллюстрации» не совпадали
# <app>.urls.py
urlpatterns = [
path("", ArticleListView.as_view(), name="home"), # This is index.html,
path("articles/<slug:slug>", ArticleDetailView.as_view(), name="article_detail"),
path("illustrations", views.illustrations, name="illustrations"),
]
Примечание:
Второй способ приближает вас к более «традиционной» схеме именования URL/API. Я бы предложил вам также изменить ListView на «/articles/». Это не проблема, когда у вас только одно приложение, но как только вы добавите еще одно (например, «editorials» или что-то в этом роде), будет легко продублировать схему URL с «/editorials/» и «/editorials/».
Совет:
Оцените django-debug-toolbar, если у вас возникнут проблемы с шаблонами/вьюшками/урлами и т.д. <5 минут на настройку и дает НАМНОГО больше полезной отладочной информации, чем ванильный django.
Другие советы:
Если вы добавляете префикс «app» в урлы, сделайте это в project.urls
файле, в который вы импортируете файл .urls (тогда вы сможете сохранить существующую структуру имен в /urls, поскольку каждый урл будет иметь префикс «your_app/» к урлу.
Вы не должны разделять файл url, особенно с одним приложением. Это не неправильно, но может облегчить поиск, если все урлы будут вместе.