Ответ 1
Наиболее разумным решением является передача списка URL-адресов в файле JavaScript и наличие на клиенте эквивалента JavaScript()(). Единственное возражение может заключаться в том, что раскрывается вся структура URL.
Я использую 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.
Наиболее разумным решением является передача списка URL-адресов в файле JavaScript и наличие на клиенте эквивалента JavaScript()(). Единственное возражение может заключаться в том, что раскрывается вся структура URL.
Существует еще один метод, который не требует раскрытия всей структуры url или ajax-запросов для разрешения каждого URL-адреса. Хотя это не очень красиво, он просто ударяет остальных:
var url = '{% url blog_view_post 999 %}'.replace (999, post_id);
(blog_view_post
URL не обязательно должны содержать магический номер 999
).
Справившись с этим, я придумал немного другое решение.
В моем случае я хотел, чтобы внешний 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()
для меня.
Хорошо предположить, что все параметры от 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' },
});
Как и Анатолий, ответьте, но немного более гибким. В верхней части страницы:
<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>
Затем вы можете сделать что-то вроде
url = window.myviewURL.replace('foobar','my_id');
или что угодно. Если ваш URL-адрес содержит несколько переменных, просто запустите метод replace несколько раз.
Мне нравится идея Анатолия, но я думаю, что использование определенного целого числа опасно. Обычно я хочу указать имя объекта 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>
Это легко распространяется и на несколько аргументов, а отображение для конкретного аргумента видно непосредственно в шаблоне.
Я нашел для вас простой трюк. Если ваш URL-адрес выглядит так:
"xyz/(?P<stuff>.*)$"
и вы хотите отменить в JS без фактического предоставления материала (отсрочивая время выполнения JS для его предоставления) - вы можете сделать следующее:
Измените представление, чтобы дать параметру значение по умолчанию - none и обработать его, отвечая с ошибкой, если он не установлен:
views.py
def xzy(stuff=None):
if not stuff:
raise Http404
... < rest of the view code> ...
"xyz/(?P<stuff>.*)?$"
И в коде js шаблона:
.ajax({ url: "{{url views.xyz}}" + js_stuff, ...... })
Сгенерированный шаблон должен иметь URL-адрес без параметра в JS, а в JS вы можете просто конкатенировать по параметрам (-ам).
Одним из решений, с которыми я пришел, является создание 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");
} );
Используйте этот пакет: https://github.com/ierror/django-js-reverse
У вас будет объект в вашем JS со всеми URL-адресами, определенными в django. Это лучший подход, который я нашел до сих пор.
Единственное, что вам нужно сделать, это добавить созданный js в голову базового шаблона и запустить команду управления для обновления сгенерированных js каждый раз, когда вы добавляете URL-адрес