Введение
Список дел – это довольно простое пример пример, которое часто делается как один из первых проектов, сегодня мы сделаем его немного интереснее, используя несколько интересных технологий.
В качестве бэкэнда мы будем использовать Django и Django REST Framework, а Alpine.js + Axios, чтобы склеить все это все вместе на интерфейсе.
Что такое Alpine.js.
Довольно новая Lightwave Framework, вдохновленные Vue.js, созданные в прошлом году Caleb Porzio, это дает реактивность реактивности и деклавированию реагирования и VUE, сохраняя его, сохраняя его, сохраняя его свет, и в доме. Это описывается как ходки для js. И я в значительной степени согласен с этим, используя его вместе с Taillwind – отличный повышение к производительности при выполнении интерфейса, потому что вы можете оставаться в одном HTML-файле и сохранить запись HTML, CSS и JS.
Axios.
Это асинхронный HTTP-клиент для JS.
Здесь ссылка на готовый проект Github Repo
Начиная приложение
Давайте начнем с создания новой виртуальной среды для нашего проекта и установить необходимые пакеты, затем создайте новый проект Django и Приложение списков
pip install Django pip install djangorestframework django-admin startproject todo_list cd todo_list django-admin startapp lists
Тогда иди к [settings.py] (http://settings.py)
и добавить Списки
и Django Ress Framework App в Install_apps.
INSTALLED_APPS = [ ... 'rest_framework', 'lists', ]
Создание моделей приложений
Давайте создадим модели БД для нашего приложения To-Do. Мы собираемся определить 2 модели, модель списка и модель задач, каждый пользователь может создать столько списков, так как он/Она хочет, а затем добавить несколько задач в каждый список.
from django.contrib.auth.models import User from django.db import models class List(models.Model): title = models.CharField(max_length=75) user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='lists') created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) class Task(models.Model): parent_list = models.ForeignKey(List, on_delete=models.CASCADE, related_name='tasks') title = models.CharField(max_length=75) completed = models.BooleanField(default=False, blank=True) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True)
Мы создали Список
Модель с полем заголовка и отношение к пользователю, создало список.
Задача
Модель, имеет отношение к Список
Объект, название и логическое значение для полного статуса задачи.
Также для обеих моделей также 2 поля DateTime для создания и обновленного времени.
Перейти к [admin.py] (http://admin.py)
Файл и зарегистрируйте модели в панели администратора
from django.contrib import admin from .models import List, Task admin.site.register(List) admin.site.register(Task)
Запустите Макемиграция
и мигрировать
команды.
python manage.py makemigrations python manage.py migrate
Создать API
Создавать сериализаторы
Внутри приложения списков Создайте новый пакет Python (новый каталог с пустым __init__.py
файл) и позвоните в него API.
. Там создать файл [serializers.py] (http://serializers.py)
, ,
[URLS.PY] (http://urls.cy)
файлы внутри. Перейти к [serialziers.py] (http://serialziers.py)
и создавать сериализаторы для моделей.
from rest_framework import serializers from ..models import List, Task class TaskSerializer(serializers.ModelSerializer): class Meta: model = Task fields = ('title', 'completed', 'parent_list') class ListSerializer(serializers.ModelSerializer): tasks = TaskSerializer(many=True, read_only=True) class Meta: model = List fields = ('title', 'tasks')
Создать оформления
Теперь мы создадим Carsets, которые автоматически предоставят нам конечные точки создания, чтения, обновления и удаления (CRUD), поэтому мы можем избежать повторения и записи их для каждой модели. В [Просмотр] (http://views.py)
Файл Создание призваний.
from rest_framework import viewsets from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from .serializers import TaskSerializer, ListSerializer from ..models import Task, List class ListViewSet(viewsets.ModelViewSet): queryset = Task.objects.all() serializer_class = ListSerializer authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated] def get_queryset(self): user = self.request.user return List.objects.filter(user=user) def create(self, request, *args, **kwargs): serializer = ListSerializer(data=request.data) if serializer.is_valid(): serializer.save(user=request.user) return Response(serializer.validated_data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class TaskViewSet(viewsets.ModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer authentication_classes = [SessionAuthentication] permission_classes = [IsAuthenticated] def get_queryset(self): user = self.request.user return Task.objects.filter(parent_list__user=user)
Регистрация маршрутов
Теперь мы создадим маршрутизатор для автоматического зарегистрирования URL-маршруты для наших моделей. Открыть URLS.PY
…
from django.urls import path, include from rest_framework import routers from . import views router = routers.DefaultRouter() router.register("lists", views.ListViewSet) router.register("tasks", views.TaskViewSet) app_name = "lists" urlpatterns = [ path("", include(router.urls)), ]
И, наконец, включить их в главную [URLS.PY] (http://urls.cy)
проекта.
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path("api/", include("lists.api.urls", namespace="api")), ]
Сайт Backend
Теперь иди к Списки/Просмотр .py
и создавать маршруты для дома, а список detali wiseurls
from django.contrib.auth.decorators import login_required from django.shortcuts import render, get_object_or_404 from .models import List @login_required def home(request): return render(request, 'index.html', { 'lists': request.user.lists.all() }) @login_required def list_detail(request, list_id): user_list = get_object_or_404(List, id=list_id) return render(request, 'detail.html', { 'list': user_list })
Теперь создайте [URLS.PY] (http://urls.cy)
Файл внутри Списки
Приложение и зарегистрируйте домашний маршрут.
from django.urls import path from . import views app_name = 'lists' urlpatterns = [ path(″, views.home, name='home'), path('list//', views.list_detail, name='detail'), ]
Теперь перейдите к главному [URLS.PY] (http://urls.cy)
Файл внутри каталога проекта TODO_LIST и включите списки
URL-адреса приложений.
from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path("api/", include("dashboard.api.urls", namespace="api")), path(″, include('lists.urls', namespace='lists')), ]
Внешний интерфейс
Мы сделаем с Backend, теперь давайте создадим наш интерфейс. В Списки
Приложение Создайте каталог, называемые шаблонами, а внутри создавать 3 файла base.html.
, index.html
и Detail.html.
.
base.html.
{% block title %} {% endblock %} {% block content %} {% endblock %}To-Do List App
Written with Django, Django Rest Framework, TailwindCSS, Alpine.js
Это файл base.html для нашего приложения, в голове, мы создали блок шаблона Django для заголовка и включен Tailwindcss
Для стайлинга нашего приложения Alpine.js
и Axios
Для изготовления ASYNC HTTP-запросов.
В тег тела мы создали блок контента
index.html.
{% extends "base.html" %} {% block title %} To-Do List App {% endblock %} {% block content %} {% endblock %}
В Index.html мы заполняем блоки содержимого, создавая, ввод с кнопкой для добавления новых списков,
И отображение списков пользователей, с ссылкой на якорную тег на страницу сведений. Есть также кнопка удаления.
Мы будем реализовать функциональность создания и удаления с Alpine.js и Axios.
Detail.html.
{% extends "base.html" %} {% block title %} {{ list.title }} - ToDos {% endblock %} {% block content %}{% endblock %}{{ list.title }}'s ToDos
{% for task in list.tasks.all %}
- {% endfor %}
{% if task.completed %} {% else %} {% endif %}{{ task.title }}
в Detail.html.
Мы создаем аналогичный вид с входом для добавления задач, кнопки для удаления задач и кнопку для переключения между состоянием задачи.
Теперь создайте суперпользователь и запустите сервер
python manage.py createsuperuser python manage.py runserver
Перейти к http://127.0.0.1:8000/admin/ И создайте списки пары и задачи с разными состояниями, затем перейдите к http://127.0.0.1:8000/ И вы должны увидеть вид так.
Нажав на заголовок списка, мы будем перемещены на страницу детализации списка
Теперь давайте все вместе используем Alpine.js и Axios
Представляем Alpine.js.
Пойдем на index.html
и давайте переключаем {% для списка в списках%}
быть шаблоном Alpine.js. Для этого отредактируйте код, как ниже.
Так что мы здесь сделали? Во-первых, мы добавили x-data
Атрибут Div Holding наш список из метода GetTask, который мы определили внизу в Сценарий
тег. Как видите, мы переместили шаблон Django для петли там, чтобы создать объект JSON.
Наконец, мы удалили Django для петли от UL
Элемент, и мы завернули Ли
элемент в теге шаблона. который имеет X-для
Атрибут, который цикл на массиве JSON элементов списка.
Мы использовали х -bind: href
и X-Text
Чтобы заполнить тег со значениями от JSON.
Добавление списков
Во-первых, добавьте переменную к JSON, возвращенную GetTasks (), и функцию, чтобы сделать запрос на запись
const getLists = () => { return { newList: ″, lists: [ {% for l in lists %} { 'title': '{{ l.title }}', 'id': '{{ l.id }}' }, {% endfor %} ] } }; const csrftoken = document.querySelector('#list-form > input').value; const addList = async title => { try { const res = await axios.post('/api/lists/', { title }, { headers: { 'X-CSRFToken': csrftoken }} ); location.reload(); } catch (e) { console.error(e); } };
Затем найдите входной элемент и отредактируйте его
Мы дали вклад X-модель
атрибут со значением, установленным на новичок
На кнопке мы добавляем @ yclick
слушатель, который будет спусковать addList
Функция и передайте значение NewList, если запрос успешен, он будет перезагружать страницу, чтобы показать новый элемент. Попробуйте попробуйте добавить несколько списков.
Удаление списков.
Снятие списков будет еще проще. Во-первых, добавьте новую функцию AXIOS в нашем теге сценария.
const removeList = async listId => { try { const res = await axios.delete('/api/lists/' + listId + '/', { headers: { 'X-CSRFToken': csrftoken }} ); location.reload(); } catch (e) { console.error(e); } };
Затем отредактируйте кнопку «Удалить», добавив @ yclick
атрибут и
Добавление и удаление задач
Теперь мы должны сделать то же самое для задач. Открыть detail.html
и редактировать это так.
{% extends "base.html" %} {% block title %} {{ list.title }} - ToDos {% endblock %} {% block content %}{% endblock %}{{ list.title }}'s ToDos
Здесь мы реализованы так же добавление и удаление списков задач.
Теперь давайте добавим обновление статуса задачи. Создать функцию UpdateTask.
const updateTask = async (taskId, taskStatus) => { try { const res = await axios.patch('/api/tasks/' + taskId + '/', { id: taskId, completed: taskStatus}, { headers: { 'X-CSRFToken': csrftoken }} ); location.reload(); } catch (e) { console.error(e); } };
Затем добавьте вызов функции в кнопках состояния
И это основной список дел, реализованный с Django, DRF, Alpine.js и Axios.
Следующие шаги
- Создание пользователей Регистрация и страницы
- Обновите DOM вместо страницы перезагрузки после успешных запросов AXIOS.
Я надеюсь, что вы узнали что-то новое, дайте мне следующее на Twitter , чтобы увидеть, когда я публикую новые вещи.
Оригинал: “https://dev.to/druidmaciek/todo-list-with-django-drf-alpine-js-and-axios-1h0e”