Как иметь необязательные части URL-адреса django и обратное ему [дублировать]

Предположим, у вас есть большой проект, написанный на c ++, который содержит тысячу файлов .cpp и тысячу файлов .h. И давайте предположим, что проект также зависит от десяти статических библиотек. Скажем, мы работаем над Windows, и мы строим наш проект в Visual Studio 20xx. Когда вы нажимаете Ctrl + F7 Visual Studio, чтобы начать компиляцию всего решения (предположим, что у нас есть только один проект в решении)

В чем смысл компиляции?

  • Visual Studio выполните поиск в файле .vcxproj и начните компилировать каждый файл с расширением .cpp. Порядок компиляции не определен. Поэтому вы не должны предполагать, что файл main.cpp скомпилирован сначала
  • . Если файлы .cpp зависят от дополнительных файлов .h, чтобы найти символы, которые могут или не могут быть определены в файл .cpp
  • Если существует один .cpp-файл, в котором компилятор не смог найти один символ, ошибка времени компилятора вызывает сообщение Символ x не может быть найден
  • Для каждого файла с расширением .cpp создается объектный файл .o, а также Visual Studio записывает вывод в файл с именем ProjectName.Cpp.Clean.txt , который содержит все объектные файлы, которые должны обрабатывается компоновщиком.

Второй этап компиляции выполняется Linker.Linker должен объединить весь объектный файл и построить окончательно вывод (который может быть исполняемым или библиотекой)

Шаги при связывании проекта

  • Разберите все объектные файлы и найдите определение, которое было объявлено только в заголовках (например: Код одного метода класса, как указано в p повторные ответы или событие инициализация статической переменной, которая является членом внутри класса)
  • Если один символ не может быть найден в объектных файлах, он также выполняется в дополнительных библиотеках. Для добавления новой библиотеки в project Свойства конфигурации -> Каталоги VC ++ -> Библиотечные каталоги, и здесь вы указали дополнительную папку для поиска библиотек и Свойства конфигурации -> Linker -> Input для указания имени библиотеки. -Если линкер не смог найти символ, который вы пишете в одном .cpp, он вызывает ошибку времени компоновщика, которая может звучать как error LNK2001: unresolved external symbol "void __cdecl foo(void)" (?foo@@YAXXZ)

Наблюдение

  1. После того, как Linker найдет один символ, он не ищет в других библиотеках для него
  2. Порядок ссылок на библиотеки имеет значение.
  3. Если Linker находит внешний символ в одной статической библиотеке, он включает в себя символ на выходе проекта. Однако, если библиотека является общей (динамической), он не включает в себя код (символы) на выходе, но Run-Time могут возникнуть сбои

Как решить эту ошибку

Ошибка времени компилятора:

  • Убедитесь, что вы правильно выполнили синтаксический проект c ++.

Ошибка времени компоновщика

  • Определите все символы, которые вы объявляете в ваших файлах заголовков.
  • Используйте #pragma once, чтобы компилятор не включал один заголовок если он уже был включен в текущий .cpp, который скомпилирован
  • Убедитесь, что ваш exter nal library не содержит символов, которые могут вступать в конфликт с другими символами, которые вы определили в ваших файлах заголовков.
  • Когда вы используете шаблон, чтобы убедиться, что вы включаете определение каждой функции шаблона в файл заголовка для разрешения компилятор для создания соответствующего кода для любых экземпляров.
128
задан CIGuy 11 September 2013 в 19:55
поделиться

4 ответа

Существует несколько подходов.

Один из них заключается в использовании fancy regex ... (?:/(?P<title>[a-zA-Z]+)/)? Создание маркера URL-адреса регулярного выражения Django Необязательно

Другое , проще следовать за порядком - это иметь несколько правил, которые соответствуют вашим потребностям, все указывают на один и тот же вид.

urlpatterns = patterns('',
    url(r'^project_config/$', views.foo),
    url(r'^project_config/(?P<product>\w+)/$', views.foo),
    ulr(r'^project_config/(?P<product>\w+)/(?P<project_id>\w+)/$', views.foo),
)

Имейте в виду, что в вашем представлении вам также необходимо установить значение по умолчанию для необязательный параметр URL, или вы получите сообщение об ошибке:

def foo(request, optional_parameter=''):
    # Your code goes here
304
ответ дан Community 24 August 2018 в 06:23
поделиться

Вы можете использовать вложенные маршруты

Django & lt; 1.8

urlpatterns = patterns(''
    url(r'^project_config/', include(patterns('',
        url(r'^$', ProjectConfigView.as_view(), name="project_config")
        url(r'^(?P<product>\w+)$', include(patterns('',
            url(r'^$', ProductView.as_view(), name="product"),
            url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
        ))),
    ))),
)

Django> = 1.8

urlpatterns = [
    url(r'^project_config/', include([
        url(r'^$', ProjectConfigView.as_view(), name="project_config")
        url(r'^(?P<product>\w+)$', include([
            url(r'^$', ProductView.as_view(), name="product"),
            url(r'^(?P<project_id>\w+)$', ProjectDetailView.as_view(), name="project_detail")
        ])),
    ])),
]

Это намного больше DRY (скажем, вы хотели переименовать product kwarg в product_id, вам нужно изменить строку 4, и это повлияет на приведенные ниже URL.

Отредактировано для Django 1.8 и выше

35
ответ дан Jacob Valenta 24 August 2018 в 06:23
поделиться

Еще проще использовать:

(?P<project_id>\w+|)

. «(a | b)» означает a или b, поэтому в вашем случае это будет один или несколько символов слова (\ w +) или ничего .

Таким образом, это будет выглядеть так:

url(
    r'^project_config/(?P<product>\w+)/(?P<project_id>\w+|)/$',
    'tool.views.ProjectConfig',
    name='project_config'
),
20
ответ дан Juan José Brown 24 August 2018 в 06:23
поделиться

Думаю, я бы добавил немного к ответу.

Если у вас несколько определений URL-адресов, вам придется называть их каждый отдельно. Таким образом, вы теряете гибкость при вызове reverse, поскольку один обратный будет ожидать параметр, а другой - нет.

Другой способ использования регулярного выражения для размещения необязательного параметра:

r'^project_config/(?P<product>\w+)/((?P<project_id>\w+)/)?$'
8
ответ дан tarequeh 24 August 2018 в 06:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: