@AndrewRusinas

Как правильно обработать urls в django?

Изучаю Python по книге Эрика Мэтиза. Выполняю задание по разработке сайта на Django. Есть огромная проблема, связанная с разными версиями джанги. Сейчас актуальная 2.1, в книге 1.9, в связи с этим есть критические нестыковки.

Конкретно сейчас столкнулся с такой вещью. В файл urls.py нужно внести изменения:
...
url(r'', include('learning_logs.urls', namespace = 'learning_logs')),


И затем создать в другой папке файл, который подключается выше со следующим содержимым.

from django.conf.urls import url
from . imprt views
urlpatterns = [
    url(r'^&', views.index, name='index'),


В новой версии файл urls.py существенно отличается от описанного в книге. Хотя бы тот факт, что вместо "url, include" импортируется новый класс path. Я отформатировал код в соответствии с новыми правилами следующим образом (не уверен, на сколько правильно):
urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', learning_logs.urls, namespace='learning_logs'),
]

И файл urls.py в папке learning_logs (лежит на уровень выше):
from django.urls import path
from . import views

urlpatterns = [
    # Домашняя страница
    path(r'^&', views.index, name='index'),
]

Но PowerShell кидает ошибку
name 'learning_logs' is not defined

И глушит сервер.

В данный момент из-за этого встал весь процесс тестовой разработки, буду очень рад помощи. :)
  • Вопрос задан
  • 13591 просмотр
Решения вопроса 1
JawsIk
@JawsIk
Python Django, Lua, ЧПУ-станки(ArtCam, Aspire)
Да всё ты правильно делал. В джанге второй всё даже проще. Со временем разберёшься, только попробуй (хоть оно и на английском) пусть даже с переводчиком (как и я) почитать официальную документацию по path. Ну а в твоём случае делается следующее:

1. в файл urls.py (главный, тот который лежит в папке с названием твоего проекта) нужно импортировать модуль include. Обычно там уже модуль path импортирован, поэтому просто нужно добавить include, чтобы строчка выглядела так:
from django.urls import path, include

2. Соответственно ниже код у тебя должен быть подобного вида:
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(learning_logs.urls), namespace='learning_logs'),
]

namespace (да и name) даже и не знаю нужен ли вообще в данном случае, ибо это же у тебя главный urls.py и в своих шаблонах ты можешь просто использовать '/' (прямую косую черту)
<a class="main" href="/">Главная</a>
да и в шаблонах этот же критерий можно использовать даже в качестве условий:
{% if not request.get_full_path == '/' %}
(в данном случае, условие означает, если текущая страница не главная (корневая), (но get_full_path нужно написать самому.))

3. А вот уже во-внутреннем urls.py (тот который лежит в папке твоего приложения learning_logs), я бы использовал уже параметр name=:
from django.urls import path
from . import views

urlpatterns = [
   # и т.д. пишешшь више чем нижняя строка
    path('result/', views.result, name='result'),
    path('', views.index, name='index'),
]


Это твой как бы для тебя. Хотя я бы для себя это всё написал в главном urls.py, если приложение не большое. И оно одно. Кроме того я не выполняю (from . import views), а делаю это явным образом (контролируя и дописывая нужное в процессе написания). Обычно у меня главный urls.py файл выглядит как-то так:
from django.contrib import admin
from django.urls import path, include
# тут могут быть и другие импорты например для статических файлов

urlpatterns = [
    path('admin/', admin.site.urls),
    path('tst/', include('tst.urls')),
    path('', include('shop.urls')),
]

а во внутренний файл уже выглядит следующим образом:
from django.urls import path
from django.views.generic import TemplateView
from shop.views import (
    base_view,
    category_view,
    product_view,
    cart_view,
    add_to_cart_view,
    remove_from_cart_view,
    add_to_cart_js_view,
    remove_from_cart_js_view,
    change_item_qty_view,
    checkout_view,
    order_create_view,
    make_order_view,
)

urlpatterns = [
    path('category/<slug:slug>', category_view, name='category_detail'), # если нужно отправить в метод slug
    path('product/<slug:slug>', product_view, name='product_detail'), # тоже самое
    path('cart/', cart_view, name='cart_detail'),  # просто переходим
    path('add_to_cart/<int:pk>', add_to_cart_view, name='add_to_cart'), # если нужно отправить id ключа например
    path('add_to_cart_js/', add_to_cart_js_view, name='add_to_cart_js'),
    path('remove_from_cart/<slug:slug>', remove_from_cart_view, name='remove_from_cart'),  # снова slug
    path('remove_from_cart_js/', remove_from_cart_js_view, name='remove_from_cart_js'),
    path('change_item_qty/', change_item_qty_view, name='change_item_qty'),
    path('checkout/', checkout_view, name='checkout'),
    path('order/', order_create_view, name='create_order'),
    path('make_order/', make_order_view, name='make_order'),
    path('thank_you/', TemplateView.as_view(template_name='thank_you.html'), name='thank_you'), # вот тут даже класса во views.py не создаётся, а сразу напрямую отправляемся в шаблон (работает потому что импортирована функция вверху).
    path('', base_view, name='base'),
]


ну я так часть взял, часть убрал, чтобы было наглядно понятно. Вообще всё с опытом. Дерзай.

p.s. и последнее:
Но PowerShell кидает ошибку
name 'learning_logs' is not defined

И глушит сервер.


у тебя всё называется одинаково и поэтому ты путаешься сам. Подумай над названиями. А по факту всё это произошло, из-за вот этого (см. жирным):
path(r'', learning_logs.urls, namespace='learning_logs'),
Потому что в данном случае Django пытается найти в views.py класс learning_logs и естественно его там не находит, вот и говорит тебе, что ёлки-маталки имя learning_logs не определено. (и правильно кстати говорит).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
netpastor
@netpastor
Python developer
Добавь
app_name = 'learning_logs'
в urls.py в папке learning_logs
https://docs.djangoproject.com/en/dev/topics/http/...
Ответ написан
ulkoart
@ulkoart
что мешает поставить 1.9 и действовать по книге? на этапе обучения будет не очень удобно каждый раз отвлекаться на различия версий.
Ответ написан
make_me_loco
@make_me_loco
Всякое бывало.
Для Django 2.х
Главный файл:
from django.urls import path, include
from django.contrib import admin

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


Внутренний:
from django.urls import path

from . import views

app_name = 'learning_logs'
urlpatterns = [
    path('', views.index, name='index'),
]
Ответ написан
Комментировать
@dastrix_dude
Djnago 2.1 не поддерживает регулярные выражения типаr'^&' для их использования на до подключить from django.urls import re_path
что крайне не рекомендуется
Гуглите URL dispatcher и сами все увидите
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы