Нам нравится язык шаблонов Django. Он прост, имеет множество готовых функций, таких как i18n, а также встроенные теги и фильтры шаблонов. Тем не менее, использование HTML / CSS / JS только ограничивает ваши возможности по созданию модного и реактивного приложения, особенно если ваш проект поддерживается API.
- Планируете ли вы создать красивое одностраничное приложение, но у вас жесткие сроки для первого прототипа?
- У вас вообще есть сомнения по поводу создания одностраничного приложения?
- Вы ориентируетесь на быстрые результаты и функциональность?
- Вы просто хотите обогатить свое приложение Django?
Тогда у меня есть кое-что для вас.
tl; dr: Используйте виджеты Vue.js, чтобы улучшить свои шаблоны Django. Пример:
<image-list></image-list>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
Vue.component('image-list', {
data: function () {
return {
images: [],
}
},
template: `
<div>
<h1>{% trans "Images" %}</h1>
<ul v-cloak v-if="images.length">
<li v-for="image in images">
<img :src="image.src" :alt="image.alt" />
</li>
</ul>
</div>
`,
beforeMount: function () {
// Get images
let el = this;
axios('{% url "api-user-images" %}')
.then(function(res) {
el.images = res.data;
});
}
});
</script>
Хотя могут быть причины, по которым вы не хотите сразу начинать работу с одностраничным приложением («SPA). Особенно, если речь идет о быстром прототипировании. Создание SPA может потребовать больших усилий, особенно в отношении процессов развертывания, и вы можете пойти в неправильном направлении. В отличие от этого, Django позволяет создать надежный прототип, который по умолчанию имеет множество основных функций:
- Аутентификация
- Формы и проверка полей формы
- ORM
- Общие функции, такие как представления на основе классов
- Интернационализация и локализация
Если вы планируете использовать API, используйте django-rest-framework (REST) или graphene (GraphQL), которые очень легко реализовать.
Подсказка: вы можете повторно использовать свои формы Django при использовании графена :)
Как вы знаете, добавление упомянутых выше функций с использованием интерфейсных фреймворков занимает некоторое время. Настройка прототипа Django с базовыми функциями занимает гораздо меньше времени и является очень гибкой. Django и его функции настолько хорошо организованы, что вашему прототипу обычно не требуется много кода.
Время - деньги, и быстрое создание прототипа приносит удовлетворение
Чтобы продемонстрировать эффективность Django, давайте спланируем задачи для небольшого приложения, которое позволяет загружать изображения, назначает их пользователю и показывает их в профиле пользователя.
- Сначала настройте проект Django (django-admin startproject mysite)
- Определите модель Django, которая хранит изображение и соединение пользователя
- Включите аутентификацию, включите urls аутентификации и
- Напишите
CreateView, который отображает форму загрузки - Добавить шаблон для формы загрузки
- Добавьте
DetailView, который показывает отдельных пользователей
Вот и все. Не займет и часа. Красота в этом - гибкость. Если вам нужно больше полей, просто добавьте их в модель, и они автоматически появятся в форме (и будут автоматически проверены). Если вам нужны представления для удаления или обновления изображений, вы также можете добавить их с минимальными усилиями, используя представления на основе классов.
Я нашел это очень полезным во времена раннего прототипирования, когда требования и мнения часто меняются.
Прототип должен волновать
Создание прототипа с помощью Django эффективно, но результаты очень простые. Ваши клиенты / друзья / коллеги измеряют ваш прототип с помощью современных приложений. Итак, нам нужно добавить немного магии. Магия JavaScript. Мы не любим перенаправления, нам нужны вызовы AJAX. Мы хотим сохранить состояние текущих компонентов и упростить их переупорядочивание / изменение / добавление / удаление. Эти навороты покрываются несколькими JS-фреймворками.
Теперь мы по-прежнему хотим использовать причудливые встроенные функции Django, такие как аутентификация и перевод. Так почему бы не объединить традиционные сверхспособности Django с современным внешним видом JS?
Что это обозначает? Это означает использование представлений, форм и шаблонов Django и их дополнения виджетами JavaScript. Под виджетами я подразумеваю отдельные компоненты, которые можно вставлять в шаблоны html.
В Bitlab Studio мы обычно предпочитаем React. React мощный, но тяжелый. Настроить SPA легко, но нельзя просто вставить React в шаблоны Django. С Vue.js это возможно. Без какой-либо настройки.
Если вы хотите создать SPA после того, как ваш прототип был рассмотрен и одобрен, легко переместить уже созданные виджеты в новый SPA. Так что на самом деле вы не теряете время зря.
Итак, теперь я покажу вам, как создавать виджеты Vue.js и обогащать их всеми прекрасными функциями Django и наоборот.
Примеры синергии
Давайте создадим панель инструментов, на которой будут отображаться изображения текущего пользователя.
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.generic.views import DetailView
@method_decorator(login_required, name='dispatch')
class UserImagesView(DetailView):
model = User
def get_object(self, *args, **kwargs):
return self.request.user
Используя декоратор аутентификации, вам больше не придется беспокоиться обо всем рабочем процессе аутентификации.
Добавьте представление к своим URL-адресам.
from django.conf import settings
from django.contrib import admin
from django.contrib.auth.views import LoginView, LogoutView
from django.conf.urls.static import static
from django.urls import path
from . import views
urlpatterns = [
path('login/', LoginView.as_view(), name='login'),
path('logout/', LogoutView.as_view(), name='logout'),
path('admin/', admin.site.urls),
path('', views.DashboardView.as_view(), name='dashboard'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Теперь создайте базовый шаблон.
{% load i18n %}
<html>
<head>
<title>{% trans "Dashboard" %}</title>
</head>
<body>
<h1>{% trans "Dashboard" %}</h1>
</body>
</html>
Конечно, теперь мы могли использовать язык шаблонов Django для отображения изображений. Но поскольку мы хотим делать необычные вещи и манипулировать DOM, мы можем обслуживать контент через Vue.js. После перехода на SPA мы можем скопировать компоненты, которые мы уже создали.
{% load i18n %}
<html>
<head>
<title>{% trans "Dashboard" %}</title>
</head>
<body>
<div id="app">
<image-list></image-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const app = new Vue({
el: '#app'
});
Vue.component('image-list', {
data: function () {
return {
images: [
{% for image in object.images.all %}
{ src: '{{ image.src }}', alt: '{{ image.alt }}' }{% if not forloop.last %},{% endif %}
{% endfor %}
]
}
},
template: `
<div>
<h1>{% trans "Dashboard" %}</h1>
<ul v-cloak v-if="images.length">
<li v-for="image in images">
<img :src="image.src" :alt="image.alt" />
</li>
</ul>
</div>
`
});
</script>
</body>
</html>
Ты видишь это? Вы можете легко использовать теги шаблонов Django в своем JS-коде.
Вы, конечно, уже можете добавить некоторые вызовы API, что упрощает перенос компонентов Vue.js в SPA.
{% load i18n %}
<html>
<head>
<title>{% trans "Dashboard" %}</title>
</head>
<body>
<div id="app">
<image-list></image-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const app = new Vue({
el: '#app'
});
Vue.component('image-list', {
data: function () {
return {
images: []
}
},
template: `
<div>
<h1>{% trans "Dashboard" %}</h1>
<ul v-cloak v-if="images.length">
<li v-for="image in images">
<img :src="image.src" :alt="image.alt" />
</li>
</ul>
</div>
`,
beforeMount: function () {
// Get images
let el = this;
axios('{% url "api-user-images" %}')
.then(function(res) {
el.images = res.data;
});
}
});
</script>
</body>
</html>
Иногда синтаксис Vue.js и Django противоречит друг другу. В этом случае используйте тег verbatim, чтобы Django игнорировал содержащийся в нем код.
{% verbatim %}
<div v-if="image">{{ image.src }}</div>
{% verbatim %}
Вы также можете использовать настройку разделители. Спасибо Раффаэле за подсказку.
new Vue({
delimiters: ['${', '}']
})
Для форм вы можете использовать тег csrf_token в Django.
<form id="form" v-on:submit.prevent="submitForm">
{% csrf_token %}
...
</form>
<script>
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const form = new Vue({
el: '#form',
methods: {
submitForm: function() {
...
axios({
url: '/',
method: 'post',
headers: {'X-CSRFToken': getCookie('csrftoken')},
data: {what: 'ever'}
});
...
}
}
});
</script>
Но почему?
У каждого решения есть свои достоинства и недостатки. Причина, по которой мне лично нравится такой подход, - это скорость, гибкость и прагматизм. Мне также нравится удобство, обеспечиваемое фреймворками, поэтому я не хочу пропустить ни один из них. Вместо этого я предпочитаю так или иначе объединять их силы.
Если возникнут вопросы, оставьте, пожалуйста, комментарий. Если вы думаете, что чтение того стоило, пожалуйста, оставьте несколько аплодисментов.
Ваше здоровье!