Нам нравится язык шаблонов 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>
Но почему?
У каждого решения есть свои достоинства и недостатки. Причина, по которой мне лично нравится такой подход, - это скорость, гибкость и прагматизм. Мне также нравится удобство, обеспечиваемое фреймворками, поэтому я не хочу пропустить ни один из них. Вместо этого я предпочитаю так или иначе объединять их силы.
Если возникнут вопросы, оставьте, пожалуйста, комментарий. Если вы думаете, что чтение того стоило, пожалуйста, оставьте несколько аплодисментов.
Ваше здоровье!