Django 및 Alpine의 간단한 작업 목록입니다.Js, Tailwidcss 및 Axios
70069 단어 djangoalpinewebdevtailwindcss
이 강좌에서, 나는 당신에게 어떻게 사용하는지 보여 드리겠습니다
백엔드
먼저 새 프로젝트와 가상 환경을 만들고 Django를 설치합니다.
pip install Django
그리고 Django 프로젝트, tasks
라는 프로그램을 만듭니다.django-admin startproject todo_list .
django-admin startapp tasks
INSTALLED_APPS
파일에 작업 응용 프로그램 settings.py
을 추가합니다.INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘tasks’ # Add newly created app
]
현재 tasks
응용 프로그램과 models.py
파일로 이동하여 우리의 작업에 모델을 만듭니다from django.db import models
class Task(models.Model):
title = models.CharField(max_length=255)
completed = models.BooleanField(default=False)
간단하게 보기 위해서, 우리는 단지 두 필드 title
와 completed
를 사용해야 한다다음은 작업 상태를 읽기, 만들기, 삭제, 업데이트하는 보기를 만듭니다.
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from tasks.models import Task
def task_list(request):
tasks = [{“id”: task.id,
“title”: task.title,
“completed”: task.completed} for task in Task.objects.all()]
return JsonResponse(status=200, data=tasks, safe=False)
def create_task(request):
title = request.POST.get(‘title’)
if not title:
return JsonResponse(status=400, data={‘error’: ‘title is required’})
task = Task.objects.create(title=title)
return JsonResponse(status=201, data={‘title’: task.title,
‘completed’: task.completed,
‘id’: task.id}, safe=False)
def delete_task(request, task_id):
task = get_object_or_404(Task, pk=task_id)
task.delete()
return JsonResponse(status=204, data={‘message’: ‘task deleted’})
def update_task_status(request, task_id):
task = get_object_or_404(Task, pk=task_id)
status = request.POST.get(‘status’)
if not status:
return JsonResponse(status=400, data={‘error’: ‘status is required’})
task.completed = int(status)
task.save()
return JsonResponse(status=204, data={‘message’: ‘task status updated’})
현재, urls.py
프로그램에서 tasks
파일을 만들고, 보기를 위한 URL 루트를 만듭니다.from django.urls import path
from . import views
urlpatterns = [
path(‘tasks/’, views.task_list, name=‘task_list’),
path(‘tasks/create/’, views.create_task, name=‘create_task’),
path(‘tasks/<int:task_id>/delete/’, views.delete_task, name=‘delete_task’),
path(‘task/<int:task_id>/update/’, views.update_task_status, name=‘update_task’)
]
이제 응용 프로그램의 마스터urls.py
파일로 이동하고 작업 응용 프로그램 URL을 포함합니다.from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(‘admin/’, admin.site.urls),
path(″, include(‘tasks.urls’)),
]
마이그레이션을 실행하고 어플리케이션을 시작합니다.python manage.py makemigratinos
python manage.py migrate
python manage.py runserver
현재 HTTP 클라이언트를 사용하고 있습니다 httpie. 그러나 다른 도구를 사용할 수 있습니다 (예: postman 또는 insomia.우리의 단점을 테스트하다.다음은 제가 사용하고 있는 httpie 명령입니다.
# Making Get request to retrive task list
http http://127.0.0.1:8000/tasks
# To test the POST/DELETE request you will need to add @csrf_exempt
# decorator to the views, to bypass the csrf token check,
# so you don’t need to pass csrf token in http client.
# Once we will be building front-end part you can delete the decorator
# Making POST request to create a task
http -f POST http://127.0.0.1:8000/tasks/create/ title=“Clean the dishes”
# Making task Delete request
http -f DELETE http://127.0.0.1:8000/tasks/1/delete/
# Making POST request to update a task status
http -f POST http://127.0.0.1:8000/tasks/2/update/ status=1
데이터베이스를 채우기 위한 작업을 만듭니다.앞쪽으로 가기 전에 홈페이지를 위한 마지막 보기를 만듭니다.
views.py
파일로 이동하여 간단한 보기를 만듭니다.def index(request):
return render(request, ‘index.html’)
마지막으로 urls.py
응용 프로그램의 tasks
에 추가합니다.urlpatterns = [
path(″, views.index, name=‘index’),
path(‘tasks/’, views.task_list, name=‘task_list’),
path(‘tasks/create/’, views.create_task, name=‘create_task’),
path(‘tasks/<int:task_id>/delete/’, views.delete_task, name=‘delete_task’),
path(‘tasks/<int:task_id>/update/’, views.update_task_status, name=‘update_task’)
]
프런트 엔드
tasks
응용 프로그램에서 templates
라는 디렉터리를 만들고 index.html
라는 파일에서 만듭니다.TailwindCSS, Alpine을 포함한 CDN
<head>
의 js 및 Axios<!DOCTYPE html>
<html lang=“en”>
<head>
<meta charset=“UTF-8”>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
<meta http-equiv=“X-UA-Compatible” content=“ie=edge”>
<title>Simple ToDo List</title>
<link href=“https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css” rel=“stylesheet”>
<script src=“https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js” defer></script>
<script src=“https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js” defer></script>
</head>
<body>
</body>
</html>
작업과 작업 목록 구성 요소를 추가하기 위한 간단한 폼을 만들어야 합니다.표부터 시작합시다.본문에 작업을 추가하기 위한 입력 및 단추 추가
<div class=“max-w-4xl mx-auto mt-6”>
<div class=“text-5xl font-extrabold leading-none tracking-tight text-center”>
<h1 class=“bg-clip-text text-transparent bg-gradient-to-r from-indigo-500 via-pink-600 to-purple-900”>Simple To-Do List</h1>
</div>
<!-- Task Input -->
<div id=“task-input” class=“mt-4 flex justify-center”>
<div class=“m-4 flex”>
<input class=“rounded-l-lg p-4 border-t mr-0 border-b border-l text-gray-800 border-gray-200” placeholder=“Task Title”/>
<button class=“px-8 rounded-r-lg bg-purple-800 text-gray-100 font-bold p-4 uppercase”>Add Task</button>
</div>
</div>
</div>
이제 작업 구성 요소를 만듭니다. 완성할 작업이 필요하고, 완성하지 않은 작업이 필요합니다.
<!-- Task Input -->
<div id=“task-input” class=“mt-4 flex justify-center”>
<div class=“m-4 flex”>
<input class=“rounded-l-lg p-4 border-t mr-0 border-b border-l text-gray-800 border-gray-200” placeholder=“Task Title”/>
<button class=“px-8 rounded-r-lg bg-purple-800 text-gray-100 font-bold p-4 uppercase”>Add Task</button>
</div>
</div>
<!-- Task List -->
<div id=“task-list” class=“max-w-md mx-auto grid grid-cols-1 gap-2 mt-6”>
<!-- Task in progress -->
<div class=“p-4 bg-white hover:bg-gray-100 cursor-pointer flex justify-between items-center border rounded-md”>
<p>Uncompleted Task</p>
<button type=“button”>
<svg class=“h-6 w-6 text-gray-500 hover:text-green-500” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z” />
</svg>
</button>
</div>
<!-- Completed Task -->
<div class=“p-4 bg-white hover:bg-gray-100 cursor-pointer flex justify-between items-center border rounded-md”>
<p class=“line-through”>Completed Task</p>
<svg class=“h-6 w-6 text-green-500” xmlns=“http://www.w3.org/2000/svg” viewBox=“0 0 20 20” fill=“currentColor”>
<path fill-rule=“evenodd” d=“M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z” clip-rule=“evenodd” />
</svg>
</div>
</div>
자, 이제 HTML이 생겼습니다. 준비가 됐습니다. 알파인을 사용해서 연결합시다.js 및 Axios
우리는 먼저 앞에서 만든 초기 작업으로 목록을 채웁니다.
바디 태그를 닫기 전에
<script>
태그를 열고 Alpine 구성 요소에 대한 기능을 만듭니다.우리는 우리의 임무를 수용하기 위해
tasks
수조를 만들 것이며, 함수를 우리가 앞views.py
에서 만든 단점과 같게 할 것이다<script>
function todos() {
return {
tasks: [],
loadTasks() {},
addTask() {},
deleteTask(taskId) {},
updateTask() {},
}
}
</script>
</body>
loadTasks()
부터 시작하겠습니다.loadTasks() {
let self = this;
axios.get(’http://127.0.0.1:8000/tasks/’)
.then(function (response) {
// handle success
self.tasks = response.data;
})
.catch(function (error) {
// handle error
console.log(error);
});
}
이제 HTML로 돌아가서 x-data
속성과 x-init
을 작업 입력과 작업 목록을 포함하는 div에 추가합니다.<div x-data=“todos()” x-init=“loadTasks()” class=“max-w-4xl mx-auto mt-6”>
x-init는 구성 요소가 초기화된 후에 함수를 실행하는 데 사용되기 때문에 우리가 가지고 있는 작업 목록을 얻을 수 있습니다.현재tasklistdiv로 넘어가서 내부에 <template>
태그를 만들어서 작업 구성 요소를 봉인하고 x-for
속성을 추가해서 목록의 모든 작업을 교체합니다<!-- Task List -->
<div id=“task-list” class=“max-w-md mx-auto grid grid-cols-1 gap-2 mt-6”>
<template x-for=“task in tasks”>
<div class=“p-4 bg-white hover:bg-gray-100 cursor-pointer flex justify-between items-center border rounded-md”>
<p>Uncompleted Task</p>
<button type=“button”>
<svg class=“h-6 w-6 text-gray-500 hover:text-green-500” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z” />
</svg>
</button>
</div>
</template>
</div>
현재 페이지를 다시 불러올 때 두 개의 작업이 있어야 합니다. 작업 구성 요소를 수정하고 /tasks/
단점에서 온 데이터로 채워야 합니다.<p>
태그에서 우리는 x-text
속성과 :class
임무 상태에 따라 귀속line-through
클래스를 사용하고 마지막으로 x-show
임무 상태에 따라 정확한 임무 아이콘을 표시합니다.너의 새로운 임무 목록은 이렇다
<!-- Task List -->
<div id=“task-list” class=“max-w-md mx-auto grid grid-cols-1 gap-2 mt-6”>
<template x-for=“task in tasks”>
<div class=“p-4 bg-white hover:bg-gray-100 cursor-pointer flex justify-between items-center border rounded-md”>
<p :class=“{ ‘line-through’: task.completed }” x-text=“task.title”></p>
<button type=“button”>
<svg x-show=“!task.completed” class=“h-6 w-6 text-gray-500 hover:text-green-500” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z” />
</svg>
<svg x-show=“task.completed” class=“h-6 w-6 text-green-500 hover:text-gray-500” xmlns=“http://www.w3.org/2000/svg” viewBox=“0 0 20 20” fill=“currentColor”>
<path fill-rule=“evenodd” d=“M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z” clip-rule=“evenodd” />
</svg>
</button>
</div>
</template>
</div>
이제 입력 작업을 하도록 하겠습니다.스크립트 태그를 되돌려주고
addTask()
함수를 완성하며 taskTitle
에 새 변수를 추가합니다taskTitle: ″,
addTask() {
let self = this;
let params = new URLSearchParams();
params.append(‘title’, this.taskTitle );
axios.post(‘http://127.0.0.1:8000/tasks/create/’, params,
{
headers: { ‘X-CSRFToken’: ‘{{ csrf_token }}’ },
}
)
.then(function (response) {
self.tasks.push(response.data);
self.taskTitle = ″;
}).catch(function (error) {
// handle error
console.log(error);
});
},
이 함수에서 새 작업을 만들고 tasks
그룹에 작업을 추가하고 taskTitle
변수를 재설정하여 DOM이 업데이트됩니다.현재, 우리는 taskTitle
속성을 사용하여 x-model
입력과 귀속시키고, addTask()
단추를 눌렀을 때 @click
함수를 시작합니다<!-- Task Input -->
<div id=“task-input” class=“mt-4 flex justify-center”>
<div class=“m-4 flex”>
<input x-model=“taskTitle” class=“rounded-l-lg p-4 border-t mr-0 border-b border-l text-gray-800 border-gray-200” placeholder=“Task Title”/>
<button @click=“if (taskTitle) { addTask() } else { alert(‘task title cannot be empty’)}”
class=“px-8 rounded-r-lg bg-purple-800 text-gray-100 font-bold p-4 uppercase”>Add Task</button>
</div>
</div>
이제 두 가지 퀘스트를 추가해 볼게요. 신기해요!작업 삭제
이제 삭제 작업이 작용할 수 있도록 하겠습니다.우선, 작업 구성 요소를 수정합니다. 작업을 삭제하는 단추를 추가하면
@click
deleteTask 함수를 터치할 수 있습니다.<!-- Task List -->
<div id=“task-list” class=“max-w-md mx-auto grid grid-cols-1 gap-2 mt-6”>
<template x-for=“task in tasks”>
<div class=“p-4 bg-white hover:bg-gray-100 cursor-pointer flex justify-between items-center border rounded-md”>
<p :class=“{ ‘line-through’: task.completed }” x-text=“task.title”></p>
<div class=“flex”>
<button class=“mr-4” type=“button”>
<svg x-show=“!task.completed” class=“h-6 w-6 text-gray-500 hover:text-green-500” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z” />
</svg>
<svg x-show=“task.completed” class=“h-6 w-6 text-green-500 hover:text-gray-500” xmlns=“http://www.w3.org/2000/svg” viewBox=“0 0 20 20” fill=“currentColor”>
<path fill-rule=“evenodd” d=“M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z” clip-rule=“evenodd” />
</svg>
</button>
<button @click=“deleteTask(task.id)” type=“button”>
<svg class=“h-6 w-6 text-red-400 hover:text-red-600” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16” />
</svg>
</button>
</div>
</div>
</template>
</div>
이제 아래로 스크롤하여 deleteTask(taskId)
기능을 완성합니다.deleteTask(taskId) {
let self = this;
axios.post(‘http://127.0.0.1:8000/tasks/’ + taskId + ‘/delete/’, {},
{ headers: { ‘X-CSRFToken’: ‘{{ csrf_token }}’ }})
.then(function (response) {
let removeIndex = self.tasks.map(item => item.id).indexOf(taskId);
~removeIndex && self.tasks.splice(removeIndex, 1);
}).catch(function (error) {
// handle error
console.log(error);
});
},
이제 목록에서 작업을 삭제할 수 있습니다.작업 상태 업데이트
함수 완성
updateTask(task)
updateTask(task) {
let self = this;
let params = new URLSearchParams();
if (task.completed) {
params.append(‘status’, 0);
} else {
params.append(‘status’, 1);
}
axios.post(‘http://127.0.0.1:8000/tasks/’ + task.id + ‘/update/’, params,
{ headers: { ‘X-CSRFToken’: ‘{{ csrf_token }}’ }})
.then(function (response) {
task.completed = !task.completed;
}).catch(function (error) {
// handle error
console.log(error);
});
}
업데이트 버튼에 등록 정보 추가@click
<button @click=“updateTask(task)” class=“mr-4” type=“button”>
<svg x-show=“!task.completed” class=“h-6 w-6 text-gray-500 hover:text-green-500” xmlns=“http://www.w3.org/2000/svg” fill=“none” viewBox=“0 0 24 24” stroke=“currentColor”>
<path stroke-linecap=“round” stroke-linejoin=“round” stroke-width=“2” d=“M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z” />
</svg>
<svg x-show=“task.completed” class=“h-6 w-6 text-green-500 hover:text-gray-500” xmlns=“http://www.w3.org/2000/svg” viewBox=“0 0 20 20” fill=“currentColor”>
<path fill-rule=“evenodd” d=“M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z” clip-rule=“evenodd” />
</svg>
</button>
그것을 테스트하면 퀘스트 상태가 업데이트되고 퀘스트가 외관을 업데이트하는 것을 볼 수 있습니다!이 강좌에서 Django와 Alpine을 사용하여 간단한 업무 목록을 만드는 방법을 배웠습니다.js.
나에게 따라가서 나의 최신 문장을 따라가라.
Reference
이 문제에 관하여(Django 및 Alpine의 간단한 작업 목록입니다.Js, Tailwidcss 및 Axios), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/druidmaciek/simple-to-do-list-with-django-alpine-js-tailwidcss-and-axios-22bd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)