URL-адреса и побочные эффекты (Django) - PullRequest
4 голосов
/ 27 июня 2010

Мне интересно, считается ли нормальным (в частности, в Django) иметь URL-адрес, предназначенный только для действий с побочными эффектами, предназначенный только для доступа через POST, и который в основном невидим для пользователя. Допустим, для того, чтобы сделать это конкретным, у меня есть небольшая система обмена сообщениями на моем сайте, и из своей папки входящих сообщений пользователь должен иметь возможность делать кучу вещей, таких как:

  • Удалить сообщение
  • Отметить сообщение как прочитанное
  • Сообщить о спаме

Все эти вещи вызывают обновление страницы, но возвращаются на ту же страницу. Мне интересно, как разработать мои URL-адреса и просмотры вокруг этого. Я вижу (по крайней мере) два варианта и понятия не имею, что является более идиоматическим.

Вариант 1)

Имейте отдельный URL и просмотрите каждое действие. Таким образом, / inbox / delete-message / отображается на views.delete_message и так далее. В конце каждого из этих представлений он перенаправляет обратно в /inbox/.

Мне нравится, как эта опция четко отделена. Если пользователь каким-то образом обнаруживает, что отправляет GET-запрос в / inbox / delete-message /, это создает странную ситуацию (выдает ли я страницу с ошибкой? Молча перенаправляет их?).

Вариант 2)

Используйте один и тот же URL-адрес и представление для каждого действия и используйте параметр POST, который определяет действие. Таким образом, у меня было бы одно довольно длинное представление входящих сообщений, в котором было бы множество операторов if, проверяющих, является ли request.POST ['action'] == 'delete' или request.POST ['delete'] == 'true' или любым другим .

Этот вариант мне кажется менее понятным, но я также чувствую, что он более распространен.

Что предпочтут Джангонауты? Или есть другой вариант, который лучше, чем любой из вышеперечисленных?

Ответы [ 4 ]

2 голосов
/ 27 июня 2010

Модифицированный вариант № 1 - лучший подход. Подумайте об этом: предположим, мы не говорили о веб-приложении, а просто проектировали класс входящих сообщений. Какой из них вам больше нравится: несколько методов (delete_message(), mark_as_spam() и т. Д.) Или один большой метод (do_stuff(action))? Конечно, вы бы использовали отдельные методы.

Отдельный URL для каждого действия, каждый с отдельным представлением, является гораздо более предпочтительным. Если вам не нравится перенаправление в конце, не используйте его. Вместо этого имейте метод render_inbox(request), который возвращает HttpResponse, и вызывайте метод в конце каждого из ваших представлений. Конечно, перенаправление после POST является хорошим способом предотвращения двойных действий и всегда оставляет пользователю постоянный URL.

Еще лучше было бы использовать Ajax, чтобы скрыть действия, но это более сложное дело.

1 голос
/ 27 июня 2010

Если вы пишете приложение для обмена сообщениями в Web 2.0, вы будете использовать вызовы AJAX и вообще не будете загружать новую страницу.Процесс будет происходить так:

  1. Пользователь нажимает [удалить] для сообщения.К этой кнопке привязано действие javascript.Это действие выполняет следующие действия:

    i.Измените пользовательский интерфейс, чтобы указать, что что-то происходит (серое сообщение или поставить песочные часы).

    ii.Отправьте запрос в / messages / inbox / 1234 / delete.(где 1234 - некоторый идентификатор, который указывает, какое сообщение)

    iii.Когда ответ от сервера возвращается, он должен указывать на успех или неудачу.Отразите этот статус в текущем пользовательском интерфейсе.Например, в случае успеха обновите представление «Входящие» (или просто удалите удаленный элемент).

На стороне сервера теперь вы можете создать обработчик URL для каждого желаемого действия (т. Е. /delete, / flag и т. д.).

Если вы хотите использовать еще более подход RESTful, вы должны использовать само действие HTTP, чтобы указать действие, которое нужно выполнить.Таким образом, вместо включения delete в ваш URL, он будет в действии.Поэтому вместо GET или POST используйте DELETE /messages/inbox/1234.Чтобы установить флаг для прочитанного, используйте SET /messages/inbox/1234?read=true.

Я не знаю, насколько просто в Django реализовать эту последнюю рекомендацию, но в целом, хорошая идея - использовать протокол (вв данном случае HTTP), а не обходить его путем кодирования ваших действий в URL или параметре.

1 голос
/ 27 июня 2010

Я не думаю, что с этим вариантом что-то не так, но # 2 потенциально лучше с точки зрения производительности.После публикации действия вы можете обработать входящие без перенаправления, чтобы сократить трафик HTTP.

0 голосов
/ 27 июня 2010

Я согласен, что # 2 - лучший подход.

Но будьте осторожны с перегрузкой отправки <input /> другими методами - если пользователь использует ее с помощью ввода с клавиатуры и нажимает клавишу ввода, он не обязательно отправит ожидаемый <input />.Либо отключите автоматическую отправку при вводе, либо запрограммируйте код так, чтобы, если отправка выполнялась более чем одной вещью, было другое поле, определяющее, каким должно быть действие (например, флажок «удалить», который проверяется во времяa request.POST)

Если бы вы пошли с # 1, я бы сказал, что GET для представления только для POST должен встречаться с 405 (метод не поддерживается) - или, в случае неудачи, с 404.

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