Джанго перенаправить с помощью kwarg - PullRequest
10 голосов
/ 19 января 2012

Я новичок в Python и Django, и у меня есть вопрос, касающийся функции перенаправления.

Это уменьшенная версия моего файла views.py.

def page_index(request, error_message=''):
    print error_message

def add_page(request):
    return redirect('page_index') # this work fine
    return redirect('page_index', error_message='test') # this does not work

А вот и короткая версия моего urls.py

urlpatterns = patterns(
    'x.views',
    url(r'^$', 'page_index', {'error_message': 't'}, name='page_index'),
    url(r'^add/$', 'add_page', name='add_page'),
)

Когда я пытаюсь перенаправить на page_index без аргумента ключевого слова, все работает нормально, но когда я использую kwag, я получаю следующее сообщение об ошибке:

NoReverseMatch в / pages / add /

Реверс для 'page_index' с аргументами '()' и аргументами ключевых слов '{' error_message ':' test '}' не найден.

Что я делаю не так?

Ответы [ 4 ]

14 голосов
/ 19 января 2012

Краткий ответ: в вашей схеме URL нет места для ключевого слова error_message.

Более длинный ответ:

Функция redirect () вызывает reverse () для создания URL; он отправит браузер пользователя по этому URL-адресу, вернув HTTP-ответ с кодом состояния перенаправления 302 и новым URL-адресом. Предполагается, что любые аргументы ключевых слов, которые вы предоставляете для reverse (), должны заканчиваться как часть url - так они сообщаются пользователю.

В вашем случае, однако, URL для 'page_index` просто определен как' ^ $ '- это корневой URL, который в браузере выглядит как' http://yoursite.com/'.

Если вы хотите иметь возможность создавать перенаправление, содержащее другую информацию, вам нужно определить место для него в URL или добавить его другим способом.

Два Для этого достаточно распространены три способа:

  1. Использовать параметр запроса - это отправляет сообщение клиенту явно; если вы не будете осторожны, люди могут создать URL-адреса, чтобы ваша страница указала, что они хотят.

    return redirect(reverse('page-index')+"?error_message=test"))
    
  2. Сохраните сообщение в сеансе и извлеките его при загрузке следующей страницы - для этого необходимо, чтобы у вас были настроены сеансы, и отслеживал все на стороне сервера, а не полагался на то, что клиент отправит вас вернуть сообщение об ошибке:

    def add_page(request):
        request.session['error_message'] = 'test'
        return redirect('page-index')
    
    def page_index(request):
        print request.session.get('error_message','')
    
  3. Используйте для этого структуру сообщений - это предпочтительнее, чем специальные атрибуты сеанса, если вам не нужно слишком много «типов» сообщений на одной странице. Если все, что у вас есть, это место в вашем шаблоне для сообщения об ошибке, то это действительно просто:

    from django.contrib.messages import error
    
    def add_page(request):
        error(request, 'test')
        return redirect('page-index')
    

    И затем в вашем базовом шаблоне где-то есть такой блок (возможно, более сложный, чем этот; даже в стиле):

    {% for message in messages %}
        <p>{{ message }}</p>
    {% endfor %}
    

В обоих во всех случаях, однако, вы можете удалить аргументы из вашего urls.py - само сообщение не будет частью компонента пути URL.

 urlpatterns = patterns(
    'x.views',
     url(r'^$', 'page_index', name='page_index'),
     url(r'^add/$', 'add_page', name='add_page'),
 )
2 голосов
/ 06 ноября 2012

Вы можете создать именованный шаблон URL для каждого сообщения об ошибке и передать его в аргументе args, например:

url(r'^$', 'page_index', {'error_message': 'test'}, name='test_page_index'),

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

url(r'(?P"<"error_message">"\w+)/^$', 'page_index', name='page_index'),

(ПОЖАЛУЙСТА, УДАЛИТЕ "" вокруг "<" и ">", пришлось заключить их в квадратные скобки, иначе они будут исключены из ответа, я думаю, все, что похоже на теги html, отфильтровано)

и в представлении:

return redirect(reverse('page_index', args=['test']))
0 голосов
/ 13 июня 2018

Вы можете использовать django сообщения. Пример:

from django.contrib.auth import messages

messages.info(request, False, "success")
return redirect("app:url")

Затем в html вы можете использовать их, используя пользовательский фильтр, чтобы получить значение сообщения на основе ключа, поскольку сообщения - это не что иное, как словарь.

{% with messages_dict|get_value_from_dict:'success' as success %}
   {% if sucess %}
         $('#notification_modal').modal('open');
   {% endif %}
{% endwith %}

Пользовательский фильтр, который можно включить в папку templatetags в приложении

from django import template
register = template.Library()


@register.filter('get_value_from_dict')
def get_value_from_dict(dict_data, key):
    """
    usage example {{ your_dict|get_value_from_dict:your_key }}
    """
    if key:
        return dict_data.get(key)
    else:
    return None
0 голосов
/ 19 января 2012

redirect должен перенаправить на реальный URL (это перенаправление HTTP, а не просто вызов Python).

В вашем url conf нет сегмента error_message, даже если вы его установилитак, что по умолчанию представление функция вызывается с error_message в качестве kwarg.

Так как это ваша страница индекса, и вы, вероятно, не хотите добавлять дополнительные сегменты пути к URL, который выможет быть, взломать его с помощью GET Vars.например,

def page_index(request):
    if 'error_message' in request.GET:
        print request.GET['error_message']

from django.core.urlresolvers import reverse

def add_page(request):
    return redirect('%s?error_message=test' % reverse('page_index'))

urlpatterns = patterns(
    'x.views',
    url(r'^$', 'page_index', name='page_index'),
    url(r'^add/$', 'add_page', name='add_page'),
)

обновлено:

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

например,

from django.contrib import messages

def add_page(request):
    messages.add_message(request, messages.ERROR, 'test')
    return redirect('page_index')

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...