Networks/Django

SK networks AI Camp - Django 실습

코딩하는 Español되기 2024. 8. 6. 20:00

2024.08.06 - [Networks/Django] - SK networks AI Camp - Django와 MySQL 연결

 

위 내용에서 배웠던 걸 토대로 새로운 실습

아래 설명 전 해야 할 일 전체 정리

1. html 파일 수정(보여지는 화면)

2. model.py 수정(Class; todo_name, 상태 정의)

3. views.py 수정(def ; 기능 정의[조회&생성, 수정, 삭제])

4. urls.py 수정( url 경로 적기)

○ html 파일 수정 [templates/todolist/index.html]

    ● 만약 messages가 있으면 h4로 색깔은 #b22222로 message를 출력

    ●  form에 action(attr)이 없음 = 현재 접속한 URL로 전달한다는 의미

    ● "Enter a task here"이라는 곳의 text를 id는 form1로 Post방식으로 전송

    ● table

         - th(헤더)는 Todo item, status, Actions

         - todos에 있는 todo_name을 출력하고 status가 True 면 Completed 출력, 아니면 In progress 출력

         - 마지막 td엔는 2개의 버튼

더보기
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
</head>
<body>
    <section class="vh-100" style="background-color: #eee;">
        <div class="container py-5 h-100">
            <div class="row d-flex justify-content-center align-items-center h-100">
            <div class="col col-lg-9 col-xl-7">
                <div class="card rounded-3">
                <div class="card-body p-4">
                    {% if messages %}
                    {% for message in messages %}
                        <h4 style="color: #b22222;">{{message}}</h4>
                    {% endfor %}
                    {% endif %}
    
                    <h4 class="text-center my-3 pb-3">To Do App</h4>
                    <form method="POST" class="row row-cols-lg-auto g-3 justify-content-center align-items-center mb-4 pb-2">
                    {% csrf_token %}
                        <div class="col-12">
                            <div class="form-outline">
                            <input type="text" id="form1" class="form-control" name="new_task" placeholder="Enter a task here"/>
                            </div>
                        </div>
    
                        <div class="col-12">
                            <button type="submit" class="btn btn-primary">Add Task</button>
                        </div>
                    </form>
                    <table class="table mb-4">
                        <thead>
                            <tr>
                            <th scope="col">Todo item</th>
                            <th scope="col">Status</th>
                            <th scope="col">Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for i in todos %}
                            <tr>
                                <td>{{i.todo_name}}</td>
        
                                {% if i.status == True %}
                                    <td>Completed</td>
                                {% else %}
                                    <td>In progress</td>
                                {% endif %}
        
                                <td>
                                    <a href="{% url 'todolist-delete' i.todo_name %}"><button type="submit" class="btn btn-danger">Delete</button></a>
                                    <a href="{% url 'todolist-update' i.todo_name %}"><button type="submit" class="btn btn-success ms-1">Finished</button></a>
                                </td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
                </div>
            </div>
            </div>
        </div>
    </section>

    <script src="//d.bablic.com/snippet/6288d4c3c4c5800001a91242.js?version=3.9"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>

</body>
</html>

 

○ models.py 수정(index.html의 table의 tbody랑 맞춰주기)

from django.db import models

# Create your models here.

class todo(models.Model):
    todo_name = models.CharField(max_length=200, unique=True)
    status = models.BooleanField(default=False)

    def __str__(self) -> str:
        return self.todo_name

 

○ views.py 수정(todolist/views.py)

    ● 조회&생성, 수정, 삭제 기능

          - views.py에서 함수 생성

              * 수정과 삭제 후에는 조회로 리다이렉트 되어야 함

                So redirect에 "todolist-select"(path name)를 적어서 urls 파일 호출 후 select_todo_list 함수로 돌아가게됨.

                urls.py에 path 안의 name은 결국 전체 경로의 대명사 느낌

                 localhost:8000/ → name : todolist-select (select or insert 기능)

                 localhost:8000/update-todo/? → name : todolist-update (update 기능)

                 localhost:8000/delete-todo/? → name : todolist-delete (delete  기능)

    ● 조회& 생성 함수(def select_todo_list)

 

[기능 살펴 보기]         

1) POST로 new_task라는 이름을 받아서 공백을 제거 (Why? 사용자가 아무것도 입력 안했을 경우를 위해)

 # 브라우저에서 작성한 todo 제목(index.html 27번 줄 name과 동일하게)
new_todo = request.POST.get("new_task").strip()

2) 오류 검사 및 오류 메세지 출력

if not new_todo:
    messages.error(request, f"Error, You didn't enter todo")
else:
    # models의 todo class에 있는 todo_name
    insert_todo = todo(todo_name = new_todo)
    insert_todo.save()

 

3) models의 있는 todo 클래스에 있는 todo_name으로 new_todo 를 넣고 저장

 # models의 todo class에 있는 todo_name
insert_todo = todo(todo_name = new_todo)
insert_todo.save()

 

4) 조회하기 

context = {
     'todos': todo.objects.all()
}

return render(request, "todolist/index.html", context)

 

[전체 코드]

from django.shortcuts import render, redirect
from django.contrib import messages

from .models import todo
# Create your views here.

# 조회 & 생성
def select_todo_list(request):
    # 생성 post
    if request.method == "POST":
        # 브라우저에서 작성한 todo 제목(index.html 27번 줄 name과 동일하게)
        new_todo = request.POST.get("new_task").strip()

        if not new_todo:
            messages.error(request, f"Error, You didn't enter todo")
        else:
            # models의 todo class에 있는 todo_name
            insert_todo = todo(todo_name = new_todo)
            insert_todo.save()

    # 조회 get
    
    # index.html의 table에 todos 로 되어 있는 것
    context = {
        'todos': todo.objects.all()
    }
    return render(request, "todolist/index.html", context)


# 수정
def update_todo(request, task):
    get_todo = todo.objects.get(todo_name = task)
    get_todo.status = True
    get_todo.save()
    # urls 파일 호출 후 select_todo_list 함수로 들어오게됨
    return redirect("todolist-select")



# 삭제
def delete_todo(request, task):
    get_todo = todo.objects.get(todo_name = task)
    get_todo.delete()
    return redirect("todolist-select")

 

○ urls.py 수정 

        - urls.py에서 함수를 사용하여 경로 적기

              * "update-todo/" or "delete-todo/" 뒤에 <str :task > : index.html에서 55번 줄의 i.todo_name이 들어옴

 

[todolist/urls.py]

from django.urls import path
from .views import select_todo_list, update_todo, delete_todo

urlpatterns = [
    path('', select_todo_list, name="todolist-select"),
    path('update-todo/<str:task>', update_todo, name="todolist-update"),
    path('delete-todo/<str:task>', delete_todo, name="todolist-delete")
]

 

 

○ 서버 구동

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

 

Add task 해서 추가하고 finished 버튼을 누르면 상태가 변경(completed) 되고 delete 하면 삭제

 

아무것도 안 적으면 에러가 나오는 것까지 확인 (select_todo_list에서 if문)