□ Todo 리스트를 등록하고 조회할 수 있는 웹을 구현하고자함
□ 추가로 등록된 리스트 중 완료로 처리할 수 있고 완료된 리스트만 따로 조회할 수 있도록 구현하고자함
□ todo 라는 app을 생성하였고 app의 admin.py에 아래와 같이 추가하였음
from django.contrib import admin
from .models import Todo
admin.site.register(Todo)
□ 코드
○ M : Model 생성
from django.db import models
class Todo(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(blank=True)
created = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
important = models.BooleanField(default=False)
# __str__ 메서드는 해당 객체가 문자열로 표시될 때 사용. 여기서는 title 필드의 값을 반환하여 객체를 문자열로 표시하도록 지정
def __str__(self):
return self.title
○ V : View
- todo_post 에서 아래에 있는 app > forms.py를 바탕으로 정보를 POST 방식으로 전달하면 저장되도록 지정
- todo_detail 에서 등록된 게시글에 대한 pk를 인자로 받아 id로 처리 후 해당 글에 대한 정보를 가져오도록 지정
from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm
#리스트 보기
def todo_list(request):
todos = Todo.objects.filter(complete = False) #완료되지 않은 것만 전달하기 위해 complete = False, 필터링을 위해 .objects.filter 사용
return render(request, "todo/todo_list.html", {"todos" : todos})
#생성(등록) : post 방식
def todo_post(request):
if request.method == "POST":
form = TodoForm(request.POST) #TodoForm 요청을 POST 방식으로 form 변수에 저장
if form.is_valid(): #유효성 검사 시작
todo = form.save(commit=False) # 폼에서 제공된 데이터로 모델 인스턴스 생성 (데이터베이스에 아직 저장되지 않음)
todo.save() #데이터 저장
return redirect("todo_list") #리다이렉트 할 함수
else:
form = TodoForm()
return render(request, "todo/todo_post.html", {"form":form})
#상세보기
def todo_detail(request, pk):
todo = Todo.objects.get(id=pk)#.objects.get 과 model의 pk를 활용하여 정보를 가져오 todo로 넣음
return render(request, 'todo/todo_detail.html', {'todo': todo})
○ app > Forms
- model 값은 app>models.py에서 정의한 클래스명으로 지정하였음
- fields는 app>models.py에서 클래스 정의시 기재한 필드, 즉, 이를 바탕으로 값을 받을 필드들을 기재함
from django import forms
from .models import Todo
class TodoForm(forms.ModelForm):
class Meta:
model = Todo
fields = (
"title",
"description",
"important"
)
○ app > Urls
- '' = 127.0.0.1/app명 즉, 127.0.0.1/todo를 의미
- post/ 는 127.0.0.1/todo/post를 의미
- '<int:pk>/는 127.0.0.1/todo/N을 의미
from django.urls import path
from . import views
urlpatterns = [
path('', views.todo_list, name="todo_list"), #메인 조회페이지
path('post/', views.todo_post, name="todo_post"), #등록하기
path('<int:pk>/', views.todo_detail, name="todo_detail"), #상세보기
]
○ project > 부모 Urls
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("todo/", include("todo.urls"))
]
○ t : Template
- 조회화면 템플릿
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 목록 앱</h1>
<p>
<!--todo_post urlname을 지정하여 클릭하면 생성페이지로이동-->
<a href="{% url 'todo_post'%}"><i class="bi-plus"></i>Add Todo</a>
<a href="{% url 'done_list'%}" class="btn btn-primary" style="float:right">완료한 TODO 목록</a>
</p>
<ul class="list-group">
<!--모델객체의 pk, 제목 가져오기-->
{% for todo in todos %}
<li class="list-group-item">
<a href="{%url 'todo_detail' pk=todo.pk%}">{{ todo.title }}</a>
{% if todo.important %}
<span class="badge badge-danger">!</span>
{% endif %}
<div style="float:right">
<a href="{%url "todo_done" pk=todo.pk%}" class="btn btn-danger">완료</a>
<a href="{%url 'todo_edit' pk=todo.pk%}" class="btn btn-outline-primary">수정하기</a>
</div>
</li>
{% endfor %}
</ul>
</body>
</div>
</html>
- 등록 템플릿
※ form.as_p 는 app > forms.py에서 지정한 양식을 바탕으로 입력양식을 뿌려준다는 의미임
※ form.as_p를 바탕으로 입력받은 값을 서버로 POST 방식으로 전송되는 데 보안(위조방지)를 위해 CSRF_TOKEN을 <form>태그내에 기재
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 추가하기</h1>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<form method="POST">
<!--post방식으로 서버에 전달할때 보안을 위해 csrf_token 활용-->
{% csrf_token %}
<!--form.as_p 를 사용하면 forms.py에서 작성한 형태로 폼이 생성됨-->
{{ form.as_p }}
<button type="submit" class="btn btn-primary">등록</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</div>
</html>
- 상세보기 템플릿
<html>
<head>
<title>TODO 목록 앱</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.1/font/bootstrap-icons.css">
</head>
<body>
<div class="container">
<h1>TODO 상세보기</h1>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ todo.title }}</h5>
</h5>
<p class="card-text">{{ todo.description }}</p>
<a href="{% url 'todo_list' %}" class="btn btn-primary">목록으로</a>
</div>
</div>
</div>
</div>
</div>
</body>
</div>
</html>
'Python > Django Ⅱ' 카테고리의 다른 글
DRF 예제1 : Django REST Framework (0) | 2024.05.18 |
---|---|
Todo : Update (0) | 2024.05.15 |
Django 게시물 수정하기 (0) | 2024.05.14 |
Django Form 기능 / 게시물 등록하기 (0) | 2024.05.14 |
게시물 상세보기 페이지 구현 + get_object_or_404 (1) | 2024.05.14 |