Рубрики
Без рубрики

Список Todo с Django, DRF, Alpine. JS и Axios

ВВЕДЕНИЕ СЛУЖБЫ ДО-СДЕЛАНИЯ – это довольно простое приложение пример, которое часто делается одним из первых проектов … Теги с Python, Django, JavaScript, WebDev.

Введение

Список дел – это довольно простое пример пример, которое часто делается как один из первых проектов, сегодня мы сделаем его немного интереснее, используя несколько интересных технологий.

В качестве бэкэнда мы будем использовать 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 %}

    

    
    




    

To-Do List App

Written with Django, Django Rest Framework, TailwindCSS, Alpine.js

{% block content %} {% endblock %}

Это файл base.html для нашего приложения, в голове, мы создали блок шаблона Django для заголовка и включен Tailwindcss Для стайлинга нашего приложения Alpine.js и Axios Для изготовления ASYNC HTTP-запросов.

В тег тела мы создали блок контента

index.html.

{% extends "base.html" %}

{% block title %}
To-Do List App
{% endblock %}

{% block content %}

{{ request.user.username }}'s Lists

{% csrf_token %}
{% endblock %}

В Index.html мы заполняем блоки содержимого, создавая, ввод с кнопкой для добавления новых списков,

И отображение списков пользователей, с ссылкой на якорную тег на страницу сведений. Есть также кнопка удаления.

Мы будем реализовать функциональность создания и удаления с Alpine.js и Axios.

Detail.html.

{% extends "base.html" %}

{% block title %}
{{ list.title }} - ToDos
{% endblock %}

{% block content %}

{{ list.title }}'s ToDos

{% csrf_token %}
    {% for task in list.tasks.all %}
  • {{ task.title }}

    {% if task.completed %} {% else %} {% endif %}
  • {% endfor %}
{% endblock %}

в 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. Для этого отредактируйте код, как ниже.

{{ request.user.username }}'s Lists

{% csrf_token %}
{% endblock %}

Так что мы здесь сделали? Во-первых, мы добавили 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 %}

{{ list.title }}'s ToDos

{% csrf_token %}
{% endblock %}

Здесь мы реализованы так же добавление и удаление списков задач.

Теперь давайте добавим обновление статуса задачи. Создать функцию 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”