Django(CRUD)

김민석·2023년 6월 21일
0

Django

목록 보기
2/3
post-thumbnail

1.CRUD

CRUD란?
Create(생성), Read(읽기), Update(갱신), Delete(삭제)의 약자

CRUD(위키백과)

CRUD를 가장 잘 보여줄 수 있는 Todo목록 서비스를 개발 할 예정이다.

2. Todo 목록 웹 서비스 시작 (Todo 전체 조회기능 구현)

가상환경 세팅

python3 --version
-m venv myvenv   
source myvenv/bin/activate # mac일 경우
source myvenv/Scripts/activate # windows일 경우

장고프로젝트 생성

python manage.py startproject mytodo

todo앱 생성

python manage.py startapp todo

todo 폴더 안에 template 폴더 template 폴더안에 todo폴더
todo 폴더 안에 forms.py, models.py, urls.py 파일 생성

관리자 앱 생성

python manage.py createsuperuser

models.py(간단한 게시판 만들었을 때와 비슷한 구조)

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)

    def __str__(self):
        return self.title

pk키도 포함되어 있음!!!

migration

python manage.py makemigrations
python manage.py migrate

migration이란?
모델의 변경 내역을 DB 스키마에 적용시키는 장고의 방법

todo/admin.py

from django.contrib import admin
from .models import Todo

# Register your models here.
admin.site.register(Todo)   #관리자 페이지에 Todo 모델 등록

mytodo/urls.py

관리자 페이지 접속

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
]

3. Bootstrap(프레임워크)으로 템플릿 만들기

Bootstrap이란?
● 프론트엔드 개발을 빠르고 쉽게 할 수 있는 프레임 워크
● HTML과 CSS기반의 템플릿 양식, 버튼, 네비게이션 및 기타 페이지를 구성하는 요소 포함
● 자바스크립트를 선택적으로 확장할 수 있음
● Github의 오픈 소스로 사용 가능, 상업적 이용 가능

링크

Todo 전체 조회 템플릿

todo/templates/todo/todo_list.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/boot-strap-icons.css">
    </head>
    <body>
    <div class="container">
        <h1>TODO 목록 앱</h1>
        <p>
            <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">
            {% 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>

todos를 넘겨받아 반복문으로 todo의 제목, 중요도, 완료 및 수정 기능표현
Todo를 추가할 수 있는 링크와 완료된 Todo 목록을 볼 수 있는 링크 내용있음

전반적인 골격과 2가지 차이가 있음

1. < head > 안에 < link > 태그가 있고 여기에 bootstrap 불러옴
2. 각 태그마다 class라는것을 작성하고 있다.

Bootstrap을 사용하는 방법

1.Bootstrap홉페이지에서 css파일들을 받아와 프로젝트 폴더에 집어넣는 방식(성능↑)
2.웹 링크 형태로 제공되는 css파일을 가져다 쓰도록 참조시키는 방식

Todo전체 조회 뷰 만들기

todo/views.py

from django.shortcuts import render, redirect
from .models import Todo

def todo_list(request):
    todos = Todo.objects.filter(complete=False)  #필터
    return render(request, 'todo/todo_list.html', {'todos': todos})

완료되지 않은 Todo만 전달해야 하기 때문에 complete=False로 필터링

Todo전체 조회 URL 연결하기

todo/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.todo_list, name='todo_list'),
]

mytodo/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('todo/', include('todo.urls')),
]

Todo 전체 조회기능 구현완료!!

4.Todo 상세 조회 기능 만들기

상세조회 템플릿 만들기

todo/templates/todo/todo_detail.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/boot-strap-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>

Todo 제목과 설명 보여주고 돌아가기 버튼 구현

Todo 상세 조회뷰 만들기

todo/views.py

from django.shortcuts import render, redirect
from .models import Todo


def todo_list(request):
     ...


def todo_detail(request, pk):
    todo = Todo.objects.get(id=pk)
    return render(request, 'todo/todo_detail.html', {'todo': todo})

model의 pk키 id를 기반으로 Todo객체를 찾아 todo_detail.html으로 전단

Todo 상세조회 URL 연결하기

todo/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.todo_list, name='todo_list'),
    path('post/', views.todo_post, name='todo_post'),
 ]

5. Todo 생성기능 만들기

todo/forms.py

from django import forms
from .models import Todo


class TodoForm(forms.ModelForm):
    class Meta:
        model = Todo
        fields = ('title', 'description', 'important')

todo/templates/todo/todo_post.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/boot-strap-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">
                                {% csrf_token %} # ********** 주의
                                {{ form.as_p }}
                                <button type="submit" class="btn btn-primary">등록</button>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </body>
    </div>
</html>

Todo생성 뷰 만들기

todo/views.py

from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm


def todo_list(request):
    todos = Todo.objects.filter(complete=False)
    return render(request, 'todo/todo_list.html', {'todos': todos})


def todo_detail(request, pk):
    todo = Todo.objects.get(id=pk)
    return render(request, 'todo/todo_detail.html', {'todo': todo})


def todo_post(request):
    if request.method == "POST":
        form = TodoForm(request.POST)
        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})

POST요청
POST요청이 들어왔을 때 => 폼 검증, 데이터 저장
GET 요청
폼 포함 템플릿 페이지

todo/urls.py

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'),
]

6. Todo 수정 기능 만들기

todo/views.py

from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm


def todo_list(request):
    ...


def todo_detail(request, pk):
    ...


def todo_post(request):
    ...

def todo_edit(request, pk):
    todo = Todo.objects.get(id=pk)
    if request.method == "POST":
        form = TodoForm(request.POST, instance=todo)
        if form.is_valid():
            todo = form.save(commit=False)
            todo.save()
            return redirect('todo_list')
    else:
        form = TodoForm(instance=todo)
    return render(request, 'todo/todo_post.html', {'form': form})

Todo.objects.get()을 통해 id 값으로 구분해 폼에 전달
폼에 객체 전달할때 instance를 통해 전달 가능

todo/urls.py

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'),
    path('<int:pk>/edit/', views.todo_edit, name='todo_edit'),
]

7. Todo 완료기능 만들기

Todo 완료 템플릿 만들기

todo/templates/todo/done_list.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/boot-strap-icons.css">
    </head>
    <body>
    <div class="container">
        <h1>DONE 목록</h1>
        <p>
            <a href="{% url 'todo_list' %}" class="btn btn-primary">홈으로</a>
        </p>
        <ul class="list-group">
            {% for done in dones %}
            <li class="list-group-item">
                <a href="{% url 'todo_detail' pk=done.pk %}">{{ done.title }}</a>
                {% if done.important %}
                 <span class="badge badge-danger">!</span>
                {% endif %}
            </li>
            {% endfor %}
        </ul>
    </body>
    </div>
</html>

Todo 완료 뷰 만들기

from django.shortcuts import render, redirect
from .models import Todo
from .forms import TodoForm


def todo_list(request):
    ...


def todo_detail(request, pk):
    ...


def todo_post(request):
    ...


def done_list(request):
    dones = Todo.objects.filter(complete=True)
    return render(request, 'todo/done_list.html', {'dones': dones})


def todo_done(request, pk):
    todo = Todo.objects.get(id=pk)
    todo.complete = True
    todo.save()
    return redirect('todo_list')


def todo_edit(request, pk):
   ...

Todo 완료 URL연결하기

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'),
    path('<int:pk>/edit/', views.todo_edit, name='todo_edit'),
    path('done/', views.done_list, name='done_list'),
    path('done/<int:pk>/', views.todo_done, name='todo_done'),
]

0개의 댓글