Получение двух строк в переменной из URL в Django

#python #django #url

#python #django #url

Вопрос:

У меня возникли некоторые проблемы с отправкой более одной переменной в представление.

мой urls.py заключается в следующем:

 urlpatterns = patterns('',
    url(r'^rss/(?P<anything>[^/] )/$', 'rss.rssama.views.makerss', name='anything'),
    url(r'^$', 'rss.rssama.views.home'),    
)
  

views.py

 def maakrss(request, anything):
  

Итак, теперь требуется из www.mydomain.com/rss /[что угодно] / и отправляет «что угодно» на мой взгляд. Однако я также хочу, чтобы он отправлял другую строку в views.py , как:

www.mydomain.com/rss /[anynumber]/[anystring]/

Я пробовал это, но это не сработало:

 url(r'^rss/(?P<anynumber>[^/] )/(?P<anystring>[^/] )/$', 'rss.rssama.views.makerss', name='anynumber', name2='anystring'),
  

Но это не работает, это выдает эту ошибку: аргумент ключевого слова повторяется (urls.py, строка 17)

Итак, мой вопрос: как я могу заставить его выдавать две строки из URL?

Ответ №1:

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

 r'^/rss/(?P<anynumber>d )/(?P<anystring>. )/$'
  

Эти строки внутри <...> частей позволяют вам присваивать имя всему, чему соответствует регулярное выражение. Затем Django будет использовать это имя для передачи значения вашей функции. Следовательно, ваша функция должна иметь аргумент с тем же именем. В этом случае Django примет вызванное значение anynumber и будет использовать это значение для параметра вашей вызываемой функции anynumber . То же самое касается anystring , и эта система освобождает вас от беспокойства о том, в каком порядке расположены аргументы вашей функции.

d будет соответствовать одному или нескольким числовым символам (цифрам). Рекомендуется ограничивать регулярное выражение соответствием только числам, если это то, что вы собираетесь перехватить, а не любому символу, и надеяться, что появятся только цифры. Если вы хотите ограничить часть digits определенным количеством цифр, вы могли бы использовать d{1,4} , чтобы взять от одной до четырех цифр.

Следующая часть (?P<anystring>. ) перехватит строку, состоящую из одного или нескольких любых символов. На самом деле это соответствовало бы чему-то вроде 'letters/moreletters' , включая косую черту. В регулярных выражениях Python есть ряд «специальных последовательностей», которые могут помочь. Чтобы сопоставлять только цифры, буквы и символ подчеркивания, используйте w , как в (?P<anystring>w ) . Быть более мягким, но игнорировать пробелы или любую другую бессмыслицу, (?P<anystring>[a-zA-Z1-9:;_{}[]] чтобы перехватить множество символов. Обязательно экранируйте все, что может быть специальным символом в регулярном выражении. Однако будьте консервативны. Если вы разрешите слишком много опций, кто знает, какие ошибки вам придется исправлять позже.

Теперь перейдем к параметру name url функции. Это имя не то, под которым будут передаваться пойманные шаблоны вашим функциям. Это имя для определенного класса вызова вашей функции просмотра, которое может использоваться в качестве сокращенного в других контекстах, таких как тег шаблона {% url view-name arg1 arg2 %} . Итак, имя, которое у вас уже есть, «anything», ссылается на вызов вашей функции просмотра, передавая ей один аргумент ключевого слова, который может быть вызван как угодно. В случае, когда вы хотите передать две строки, присвойте им имя типа «rss-number-string» для обозначения аргументов, которые вы хотите принять, или имя, которое ссылается на специальную функцию, которую ваше представление будет выполнять с этой комбинацией.

Я все время использую несколько имен для одной и той же функции, и ключ в этом:

 def makerss(request, anystring=None, anynumber=None):
  

Присваивая параметрам значения по умолчанию, это позволяет вам использовать одну и ту же функцию по-разному. В этом случае функцию можно использовать, когда вы хотите передать значение только для anystring или когда anystring и anynumber должны иметь значения.

Я знаю, что это много разных моментов, поэтому я попытаюсь собрать все это воедино, чтобы вы могли увидеть, как это может работать. Чтобы иметь два URL-адреса, один из которых улавливает строку и передает ее дальше, а другой, который улавливает число, косую черту, а затем строку, но оба указывают на одну и ту же функцию просмотра, вы могли бы использовать это:

 urlpatterns = patterns('',
    url(r'^rss/(?P<anystring>w )/$', 'rss.rssama.views.makerss', name='rss-anystring'),
    url(r'^rss/(?P<anynumber>d )/(?P<anystring>w )/$', 'rss.rssama.views.makerss', name='rss-number-string'),
    url(r'^$', 'rss.rssama.views.home'),    
)
  

С помощью функции просмотра что-то вроде этого:

 def makerss(request, anystring=None, anynumber=None):
    if anystring:
        if anynumber:
            #Do something with the string and the number
        else:
            #Do something with just the string
  

Пожалуйста, дайте мне знать, если это поможет. Кроме того, Django потрясает, так что слава!

Документы библиотеки регулярных выражений Python

Комментарии:

1. Кевин, большое спасибо за твое подробное объяснение! Действительно ценю время, которое вы потратили на подробное объяснение! Теперь это работает просто великолепно! p.s. после долгих размышлений о том, что изучать (PHP и некоторые фреймворки или Django, у меня были базовые навыки php и python) Я решил использовать Django, потому что мне очень понравился Python. Даже несмотря на то, что сначала вам придется немного научиться, мне пока это действительно нравится!

2. Всегда пожалуйста. Я буду рад сделать все возможное, чтобы ответить на любые другие ваши вопросы.

Ответ №2:

На самом деле вам не нужно указывать два аргумента name для этого. Я имею в виду, у вас уже есть имена переменных внутри регулярного выражения. Реальная проблема в том, что вы не можете указать два аргумента name, поэтому вы можете сделать это вместо:

 url(r'^rss/(?P<anynumber>[^/] )/(?P<anystring>[^/] )/$', 'rss.rssama.views.makerss',name='something'),
  

Редактировать:

используя URLconf выше, вы можете создать соответствующее представление как:

 def makerss(request, anynumber, anystring):
  

Комментарии:

1. и как мне тогда получить доступ к этим двум переменным в представлениях? Теперь я получаю сообщение об ошибке: функция … получил неожиданный аргумент ключевого слова ‘anynumber’, когда я использую something[0] для получения содержимого anynumber.

2. Что? Вам действительно нужно прочитать документацию. ‘something’ не передается в представление, ‘anynumber’ и ‘anystring’ передаются.

Ответ №3:

Что name2 должно быть? url Функция принимает name параметр, который является именем URL, когда вы его переворачиваете, но вы не можете вводить случайные дополнительные функции.

В противном случае у вас есть правильный синтаксис для отправки двух элементов в представление. Конечно, поскольку вы замаскировали имена переменных и не предоставили фактическую ошибку или обратную трассировку, у нас нет способа узнать, что на самом деле происходит не так.