СУХИЕ URL в Django Javascript - PullRequest
       25

СУХИЕ URL в Django Javascript

49 голосов
/ 27 апреля 2010

Я использую Django в Appengine. Я использую функцию django reverse() везде, сохраняя все как можно более сухим.

Однако у меня возникают проблемы с применением этого к моему клиентскому JavaScript. Существует класс JS, который загружает некоторые данные в зависимости от переданного идентификатора. Существует ли стандартный способ не жестко задавать URL-адрес, с которого должны поступать эти данные?

var rq = new Request.HTML({
    'update':this.element,
}).get('/template/'+template_id+'/preview'); //The part that bothers me.

Ответы [ 9 ]

32 голосов
/ 29 июня 2012

Существует еще один метод, который не требует раскрытия всей структуры URL-адресов или запросов ajax для разрешения каждого URL-адреса. Несмотря на то, что он не очень красивый, он простит других:

var url = '{% url blog_view_post 999 %}'.replace (999, post_id);

(blog_view_post URL-адреса, конечно, не должны содержать магическое 999 число.)

9 голосов
/ 02 июня 2016

Только что поборолся с этим, я нашел немного другое решение.

В моем случае я хотел, чтобы внешний JS-скрипт вызывал вызов AJAX по нажатию кнопки (после некоторой другой обработки).

В HTML я использовал пользовательский атрибут HTML-5, таким образом

<button ... id="test-button" data-ajax-target="{% url 'named-url' %}">

Затем в javascript просто сделал

$.post($("#test-button").attr("data-ajax-target"), ... );

Что означало, что система шаблонов Django сделала всю логику reverse() для меня.

8 голосов
/ 08 октября 2011

Наиболее разумным решением является передача списка URL-адресов в файле JavaScript и наличие JavaScript-эквивалента reverse (), доступного на клиенте. Единственное возражение может заключаться в том, что вся структура URL выставлена.

Вот такая функция (из этого вопрос ).

4 голосов
/ 14 сентября 2012

Похоже на ответ Анатолия, но немного более гибко. Поместите вверху страницы:

<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>

Тогда вы можете сделать что-то вроде

url = window.myviewURL.replace('foobar','my_id');

или что угодно. Если ваш URL содержит несколько переменных, просто запустите метод replace несколько раз.

4 голосов
/ 15 апреля 2012

Хорошо бы предположить, что все параметры из JavaScript в Django будут переданы как request.GET или request.POST. Вы можете сделать это в большинстве случаев, потому что вам не нужны красивые отформатированные URL для запросов JavaScript.

Тогда единственная проблема - передать URL из Django в JavaScript. Я опубликовал библиотеку для этого. Пример кода:

urls.py

def javascript_settings():
    return {
        'template_preview_url': reverse('template-preview'),
    }

* Javascript 1011 *

$.ajax({
  type: 'POST',
  url: configuration['my_rendering_app']['template_preview_url'],
  data: { template: 'foo.html' },
});
2 голосов
/ 23 октября 2013

Мне нравится идея Анатолия, но я думаю, что использование определенного целого числа опасно. Обычно я хочу указать, скажем, идентификатор объекта, который всегда должен быть положительным, поэтому я просто использую отрицательные целые числа в качестве заполнителей. Это означает добавление -? к определению URL, например:

url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details),

Тогда я могу получить обратный URL в шаблоне, написав

{% url 'events.views.event_details' event_id=-1 %}

И используйте replace в javascript для замены заполнителя -1, чтобы в шаблоне я писал что-то вроде

<script type="text/javascript">
var actual_event_id = 123;
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id);
</script>

Это также легко распространяется на несколько аргументов, и отображение для конкретного аргумента видно непосредственно в шаблоне.

1 голос
/ 29 января 2013

Я нашел простой трюк для этого.Если ваш URL-адрес имеет вид, подобный следующему:

"xyz/(?P<stuff>.*)$"

, и вы хотите повернуть в JS без фактического предоставления материала (для этого требуется время выполнения JS) - вы можете сделать следующее:

Измените представление, чтобы задать для параметра значение по умолчанию - none, и обработайте его, ответив ошибкой, если она не установлена:

views.py

def xzy(stuff=None):
  if not stuff:
    raise Http404
  ... < rest of the view code> ...
  • Измените соответствие URL, чтобы сделать параметр необязательным: "xyz/(?P<stuff>.*)?$"
  • И в шаблоне js код:

    .ajax ({url: "{{url views.xyz}} "+ js_stuff, ... ...})

Сгенерированный шаблон должен иметь URL-адрес без параметра в JS и в JSВы можете просто объединить параметр (ы).

0 голосов
/ 30 ноября 2017

Используйте этот пакет: https://github.com/ierror/django-js-reverse

В вашем JS будет объект со всеми URL-адресами, определенными в django. Это лучший подход, который я нашел до сих пор.

Единственное, что вам нужно сделать, это добавить сгенерированный js в заголовок вашего базового шаблона и запустить команду управления для обновления сгенерированного js при каждом добавлении URL

0 голосов
/ 11 февраля 2016

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

Это может не подходить в каждом случае, но у меня есть таблица (заполненная AJAX), и нажатие на строку должно привести пользователя к единственной записи из этой таблицы.

(я использую django-restframework и Datatables ).

Каждая запись из AJAX имеет прикрепленный URL:

class MyObjectSerializer(serializers.ModelSerializer):
    url = SerializerMethodField()
    # other elements

    def get_url(self, obj):
       return reverse("get_my_object", args=(obj.id,))

при загрузке ajax каждый URL-адрес присоединяется в качестве атрибута данных к строке:

var table = $('#my-table').DataTable({
   createdRow: function ( row, data, index ) {
      $(row).data("url", data["url"])
   }
});

и при клике мы используем этот атрибут данных для URL:

table.on( 'click', 'tbody tr', function () {
  window.location.href = $(this).data("url");
} );
...