Получение 404 не найдено с использованием path() в Django

Я просто проверял django и пытался просмотреть список книг, передав id в качестве аргумента URL-адресу books/urls.py. Но при получении ошибки 404 страница не найдена. Я не понимаю, что не так с URL-адресом, когда я набрал этот URL-адрес в браузере:

 http://192.168.0.106:8000/books/list/21/

книжный магазин/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('books/', include("books.urls"))
] 

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'books'
   ]
...
...
...
ROOT_URLCONF = 'bookstore.urls'

книги/urls.py

urlpatterns = [
     path('home/', create),
     path('list/(?P<id>\d+)', list_view),
]

книги/views.py

def create(request):
    form = CreateForm(request.POST or None, request.FILES or None)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        messages.success(request, "Book Created")
        return redirect('/books/list', kwargs={"id":instance.id})
    return render(request, "home.html", {"form":form})


def list_view(request, id=None):
    books = Book.objects.filter(id=id)
    return render(request, "list.html", {"books": books})

Структура проекта:

├── books
│   ├── admin.py
│   ├── forms.py
│   ├── __init__.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── bookstore
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py

Вот скриншот — Страница 404

РЕДАКТИРОВАТЬ. Как указано в комментариях. Пытался добавить / в выражение URL-адреса thebooks.urls, но безуспешно :( Снимок экрана


person Laxmikant    schedule 16.11.2017    source источник
comment
Использование books = Book.objects.filter(id=id) выглядит немного странно. Если id — это идентификатор книги, я ожидаю увидеть book = Book.objects.get(id=id) или, возможно, book = get_object_or_404(Book, id=id).   -  person Alasdair    schedule 16.11.2017
comment
@Alasdair - На самом деле это был book_id, и это были дубликаты, поэтому заменили его на id в рамках тестирования.   -  person Laxmikant    schedule 16.11.2017
comment
Кроме того, ваша строка redirect неправильно смешивает жестко заданный URL-адрес и kwargs. Вы можете либо создать URL-адрес с помощью return redirect('/books/list/%s/' % instance.id), либо рекомендуемый подход — позволить Django изменить URL-адрес с помощью return redirect('list_view', kwargs={id:instance.id}).   -  person Alasdair    schedule 16.11.2017
comment
@Alasdair - Create работает нормально, никаких проблем. Застрял только с представлением списка при передаче id в URL-адресах. Пробовал вводить URL вручную в браузере.   -  person Laxmikant    schedule 16.11.2017
comment
Поверьте мне, redirect неверен, даже если он не выдает вам ошибку. Я предполагаю, что реверс молча завершится ошибкой и будет перенаправлен на /books/list/, игнорируя kwargs.   -  person Alasdair    schedule 16.11.2017
comment
@Alasdair - О, я исправлю, спасибо   -  person Laxmikant    schedule 16.11.2017


Ответы (1)


Вы неправильно используете новый path из Django 2.0. Вы не должны использовать регулярное выражение, такое как \d+. Попробуйте изменить его на:

 path('list/<int:id>/', list_view, name='list_view'),

name требуется, если вы хотите изменить URL-адрес.

Если вы хотите придерживаться регулярных выражений, используйте re_path (или url() все еще работает, если вы хотите быть совместимым со старыми версиями Django). Дополнительную информацию см. в документах диспетчера URL.

Обратите внимание на косую черту в конце — иначе ваш путь соответствует http://192.168.0.106:8000/books/list/21, но не http://192.168.0.106:8000/books/list/21/.

person Alasdair    schedule 16.11.2017
comment
Сработало как шарм, большое спасибо :) - person Laxmikant; 16.11.2017