Server/django

[Django] CRUD

또잉코딩 2020. 4. 16. 01:29

ORM (Object Relational Mapping)

정의하고자 하는 데이터를 클래스(객체)로 표현하는 것을 말한다.

객체로 관계형 DB를 다루기 때문에 SQL문을 사용하지 않고도 데이터베이스안에 원하는 데이터를 바로 적용 가능하다.

 

데이터를 다루는 네 가지 방법 CRUD

import 부분

from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from .models import Blog
from .form import NewBlog

C ( Create )

def create(request):
    # 새로운 데이터(새로운 블로그 글)를 저장하는 역할 == POST
    if (request.method == 'POST'):
        # 입력된 블로그 글들을 저장
        form = NewBlog(request.POST)
        if form.is_valid:
            post = form.save(commit=False)
            post.pub_date = timezone.now()
            post.save()
            return redirect('home')
    # 글쓰기 페이지를 띄워주는 역할 == GET
    else:
        # 입력받을 수 있는 form 제공
        form = NewBlog()
        return render(request, 'viewcrud/newblog.html', {'form': form})

R ( Read )

def read(request):
    blogs = Blog.objects.all()
    return render(request, 'viewcrud/viewcrud.html', {'blogs':blogs})

U ( Update )

def update(request, pk):
    # 어떤 블로그를 수정할지 블로그 객체 가져오기
    blog = get_object_or_404(Blog, pk = pk)
    # 해당하는 블로그 객체 pk에 맞는 입력공간
    form = NewBlog(request.POST, instance=blog)
    if form.is_valid:
        form.save()
        return redirect('home')
    return render(request, 'viewcrud/newblog.html', {'form':form})

D ( Delete )

def delete(request, pk):
    blog = get_object_or_404(Blog, pk = pk)
    blog.delete()
    return redirect('home') 

 

 

CBV (Class Based View - Generic View)

CBV란 클래스를 기반으로 뷰를 작성하는 것을 말한다.

함수와 클래스 비교

함수와 클래스는 '호출 가능한 객체'라는 점에서 공통점을 갖지만, 상속의 여부에 따라 나뉜다.

 

CBV이 목적은 중복의 제거, 코드의 재사용을 위해 사용한다.

하지만, 간단한 만큼 미리 약속된 디폴트 설정값들이 많아 생략 하는 것들이 있다.

 

models.py

from django.db import models

# Create your models here.
class ClassBlog(models.Model):
    title = models.CharField(max_length=100)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    body = models.TextField()

    def __str__(self):
        return self.title

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.BlogView.as_view(), name="list"),
    path('newblog/', views.BlogCreate.as_view(), name="new"),
    path('detail/<int:pk>', views.BlogDetail.as_view(), name="detail"),
    path('update/<int:pk>', views.BlogUpdate.as_view(), name="change"),
    path('delete/<int:pk>', views.BlogDelete.as_view(), name="del"),
]

views.py

from django.shortcuts import render
from django.utils import timezone

from django.urls import reverse_lazy # redirect
from django.views.generic.list import ListView # 데이터 보여주기
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView # 데이터 추가
from .models import ClassBlog
# Create your views here.

class BlogView(ListView):   # html : 블로그 리스트를 담은 html : (소문자모델)_list.html
    model = ClassBlog

class BlogCreate(CreateView):   # html : form (입력공간)을 갖고있는 html : (소문자모델)_form.html
    model = ClassBlog
    fields = ['title', 'body'] # 내가 입력할 Form Field
    success_url = reverse_lazy('list')

class BlogDetail(DetailView):   # html : 상세 페이지를 담은 html : (소문자모델)_detail.html
    model = ClassBlog

class BlogUpdate(UpdateView):   # html : form (입력공간)을 갖고있는 html : (소문자모델)_form.html
    model = ClassBlog
    fields = ['title', 'body']
    success_url = reverse_lazy('list')

class BlogDelete(DeleteView):   # html : 정말 삭제할 것인지 경고를 보내는 html : (소문자모델)_confirm_delete.html
    model = ClassBlog
    success_url = reverse_lazy('list')

classblog_list.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <!-- 글쓰기 링크(버튼) -->
    <a href="{% url 'new' %}">추가</a>
    
    <!-- 블로그 글을 띄우는 부분 -->

    <!-- object_list는 지정한 모델로 만들어진 모든 객체들의 목록이다. -->
    {% for blog in object_list %}
    <h2>{{blog.title}}</h2>
    <h5>{{blog.created_at}}</h5>
    <p>{{blog.body}}</p>
    <a href="{% url 'detail' blog.id %}">자세히보기</a>
    <a href="{% url 'change' blog.id %}">수정</a>
    <a href="{% url 'del' blog.id %}">삭제</a>
    <hr>
    {% endfor %}
</body>
</html>

classblog_detail.html

<h1>본문 자세히 보기 페이지</h1>
<hr>
<!-- object는 지정된 (pk값에 맞는) 객체이다.-->
<h2>제목 : {{object.title}}</h2>
<h4>날짜 : {{object.created_at}}</h4>
본문 : {{object.body}}

classblog_form.html

<form method="POST">
    {% csrf_token %}
    {{form.as_p}}
    <input type="submit" value="추가하기"> 
</form>

classblog_confirm_delete.html

<form method="POST">
    {% csrf_token %}
    정말 삭제하시겠습니까?<br><br>
    <input type="submit" value="YES">
</form>

 

Tip. 만약 html의 파일 이름을 디폴트 값으로 하지 않으려면

views.py 에서 해당 클래스에

template_name = '<해당 html 파일명>.html'

코드를 추가해준다.

 

Tip. 디폴트로 만들어진 객체 이름은 object이다. 그렇다면 두 개 이상의 객체를 사용해야 할 때 문제가 발생한다. 따라서, 서로 다른 객체는를 구분하기 위해서 

views.py 에서 해당 클래스에

context_object_name = '<원하는 object 이름>'

코드를 추가해준다.