Как правильно настроить файл urls.py для разных городов?

Как можно правильно организовать файл urls.py для поддержки маршрутов, относящихся к разным городам? Например, необходимо, чтобы работали запросы вида /moskva/obuchenie/, /volgograd/obuchenie/, а также /obuchenie/. То есть, одни и те же представления (views) должны функционировать как при указании города в начале URL, так и без него. Кроме того, городские названия необходимо извлекать из базы данных. Я попробовал реализовать это следующим образом, но возникли проблемы:

```python
pages = [
    path('', views.index),
    path('home/', views.index, name='home'),
    path('obuchenie/', views.obuchenie, name='obuchenie'),
]

citys = City.objects.all()

city_urls = []

for city in citys:
    if city.url:
        city_urls.append(path(city.url + '/', include(pages)))

city_urls.append(pages)

pprint(city_urls)

urlpatterns = [
    path('admin/', include([
        path('', admin.index),
        path('home/', admin.index, name='home'),
        path('config/', include([
            path("index/", login_required(admin.FilteredConfigListView.as_view()), name='config/index'),
            path("edit/<int:id>/", admin.config, {'action': 'edit'}, name='config/edit'),
        ]), name='config'),
        path('login/', admin.UserLoginView.as_view(), name='login'),
        path('logout/', admin.UserLogoutView.as_view(), name='logout'),
    ])),
    path('set-city/<str:city>', views.set_city, name='set-sity'),
    path("ckeditor5/", include('django_ckeditor_5.urls'), name="ck_editor_5_upload_file"),
    path("robots.txt",
        TemplateView.as_view(template_name="robots.txt", content_type="text/plain"),
    ),
] + city_urls

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```
  • 9 ноября 2024 г. 9:53
Ответы на вопрос 2
Для настройки вашего файла `urls.py` с поддержкой маршрутов для различных городов, можно использовать подход, который включает динамическое извлечение городов из базы данных и создание маршрутов на основе этих данных. Однако ваш текущий код имеет некоторые недостатки в части логики, а также является не совсем корректным в синтаксисе.

Вот упрощенный и исправленный вариант реализации, который делает то, что вам нужно:

```python
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import TemplateView
from . import views
from .models import City  # Убедитесь, что у вас есть модель City

# Получаем список всех городов один раз
citys = City.objects.values_list('url', flat=True)

# Создаем список маршрутов для городов
city_urls = []

# Генерируем маршруты для каждого города
for city_url in citys:
    city_urls.append(path(f"{city_url}/", include([
        path('', views.index, name='city_index'),
        path('home/', views.index, name='city_home'),
        path('obuchenie/', views.obuchenie, name='city_obuchenie'),
    ])))

# Добавляем маршруты без указания города
base_urls = [
    path('', views.index, name='home'),
    path('home/', views.index, name='base_home'),
    path('obuchenie/', views.obuchenie, name='base_obuchenie'),
]

urlpatterns = [
    path('admin/', admin.site.urls),
    path('set-city/<str:city>/', views.set_city, name='set_city'),
    path("ckeditor5/", include('django_ckeditor_5.urls'), name="ck_editor_5_upload_file"),
    path("robots.txt", TemplateView.as_view(template_name="robots.txt", content_type="text/plain")),
]

# Добавление как городских, так и базовых маршрутов в urlpatterns
urlpatterns += city_urls
urlpatterns += base_urls

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

### Объяснение кода:
1. **Модели и значения города**: Мы используем `City.objects.values_list('url', flat=True)`, чтобы извлечь все значения `url` из модели `City`. Это позволит избежать необходимости итерироваться по объектам и в дальнейшем использовать их непосредственно.

2. **Генерация маршрутов для городов**: Для каждого города мы создаем маршрут, который включает в себя префикс города. Это будет направлять к тем же представлениям, что и базовые маршруты.

3. **Базовые маршруты**: Мы определяем отдельный список базовых маршрутов, которые будут доступны без указания города.

4. **Объединение маршрутов**: В конце мы объединяем маршруты городов и базовые маршруты в общий `urlpatterns`.

### Замечания:
- **Избегайте синтаксических ошибок**: Убедитесь, что вы используете правильный синтаксис. В вашем примере вместо `&lt;` и `&gt;` нужно использовать угловые скобки `<` и `>`. 
- **Обновление данных**: Если данные о городах изменятся, вам, возможно, придется обновлять URL-ы. Убедитесь, что маршруты обновляются при каждом запуске сервера или используйте методы, чтобы обновление происходило автоматически при изменении базы данных.
В очередной раз фигну делаешь, при добавление города тебе надо будет перезагружать django 

Достаточно просто один раз добавить
'<str:city>/, '<str:city>/home/', '<str:city>/obuchenie/'
и в каждом запросе доставить city, если его нет, выдавать 404
Похожие вопросы