Подтвердить что ты не робот

Сухие URL-адреса в Django Javascript

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

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

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

Ответ 1

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

Вот такая функция (из этого question).

Ответ 2

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

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

(blog_view_post URL не обязательно должны содержать магический номер 999).

Ответ 3

Справившись с этим, я придумал немного другое решение.

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

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

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

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

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

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

Ответ 4

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

Тогда только проблема состоит в том, чтобы передать url из Django в JavaScript. Я опубликовал для этого библиотеку. Пример кода:

urls.py

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

Javascript

$.ajax({
  type: 'POST',
  url: configuration['my_rendering_app']['template_preview_url'],
  data: { template: 'foo.html' },
});

Ответ 5

Как и Анатолий, ответьте, но немного более гибким. В верхней части страницы:

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

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

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

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

Ответ 6

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

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

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

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

И используйте replace в javascript, чтобы заменить placeholder -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>

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

Ответ 7

Я нашел для вас простой трюк. Если ваш 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 вы можете просто конкатенировать по параметрам (-ам).

Ответ 8

Одним из решений, с которыми я пришел, является создание 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");
} );

Ответ 9

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

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

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