Django/응용

[Django 게시판] 1. generic View를 이용한 CRUD

민돌v 2021. 6. 13. 23:49

내 마음데로 게시판 아닌 게시판을 만들거다.

CRUD

1. Read (ListView)

Fbv 를 이용하면 여러가지 추가할 사항이 많지만 generic cbv는 간단하고 코드 문장을 간결하게 작성할 수 있다.

from django.shortcuts import render
from . import models
#CBV 사용
from django.views.generic import CreateView,ListView

#cbv
#Read(게시물 나열)
class DesignerList(ListView):
    model = models.Designer
    context_object_name = 'designer'   #객체를 부르는 이름
    template_name='home.html'    #Default 연결 값 변경

urls.py

from django import urls
from django.urls import path

from . import views

urlpatterns = [
    # path('',views.home, name ='home'),
    path('',views.DesignerList.as_view(), name='designer'),
]

* as_view()

: as_view() 함수는 클래스의 인스턴스를 생성하고, 인스턴스의 dispatch() 메소드를 호출한다. dispatch() 메소드는 요청을 검사해서 GET< POST 등의 어떤 HTTP 메소드로 요청되었는지 알아낸 다음, 인스턴스 내에서 해당 이름을 갖는 메소드로 요청을 중계해준다. 만일 해당 메소드가 정의되어 있지 않으면 HttpResponseNotAllowed 익셉션을 발생시킵니다.

*templates_name 설정 안해줬을 시 default 주소

* ListView 적용한 화면

 

* 가로로 출력

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <style>
        div {float : left}
    </style>
</head>

 

2. Create(CreateView)

이제 버튼을 하나 만들어서 모델 객체를 생성해 보겠습니다.

1) views.py 에 cbv 기반으로 사용할거니까 class를 만들어줍니다.

- CreateView를 이용해 줍니다.

- CBV 기반의 CreateView를 이용할때 보통 forms.py를 만들어 form class를 많이 이용을 하길래

저는 반대로 이용을 하지 않고 만들어 보았습니다. (자료가 증말 없어서,, 오래걸렸네,, 후)

- form class 를 사용하지않고 "fields"를 이용하면 자동적으로 ModelForm이 생성되어 인식합니다.

- CBV 기반 createview를 이용하여 file 이나 image를 업로드 하기 위해서 "form_valid" 를 정의해주어서

image 파일을 핸들링 해줘야합니다. ( 안해줘도 되긴 하던데 하는게 조금 더 확실한거 같다,,,ㅇㅇ,)

#Create(게시물 생성)
class DesignerCreate(CreateView):
    model = models.Designer
    fields = ['image', 'name', 'adress', 'description',] #ModelForm을 안써줄때 자동 생성, form_class랑 같이사용시 에러
    success_url='/' # or reverse_lazy('designer') url 이름
    template_name='create2.html'

    def form_valid(self, form):
        designer = form.save(commit=False)
        designer.adress =form.cleaned_data['image']
        
        designer.save()
        return super().form_valid(form)
        # return HttpResponseRedirect(self.get_success_url())

2) urls.py 매핑

- 뷰를 적성하였으니, url을 매핑 시킵니다.

from django import urls
from django.urls import path

from . import views

urlpatterns = [
    # path('',views.home, name ='home'),
    path('',views.DesignerList.as_view(), name='designer'),
    path('create',views.DesignerCreate.as_view(), name='create'),
]

3) tempaltes 폴더에 html을 만들어 줍니다.

- 먼저 home.html 에 버튼 만들기

<a href="{% url 'create'%}">
<button>
    디자이너 생성
</button>
</a>

- crate. html

- 이미지를 업로드 할 것이기 때문에 enctype = "multipart/form-data" 를 작성하여 데이터 형식을 변환시켜 줘야 합니다.

<form action="{% url 'create'  %}" method ='POST'  enctype = "multipart/form-data">  <!--파일을 전송할때 enctype 작성-->
    {% csrf_token %}
    <p>디자이너 생성 페이지</p>
    {{ form.as_p }}
    <br>
         <button type="submit">Create</button>
    </div>
</form>

뾰로롱

3. Delete (게시물 삭제)

-delete는 초간단하지만, pk 값을 url로 넘겨주어야 함

views.py

#Delete(게시물 삭제)
class DesignerDelete(DeleteView) :
    model = models.Designer
    template_name ='delete.html'
    success_url='/' # or reverse_lazy('designer') url 이름

urls.py

from django import urls
from django.urls import path

from . import views

urlpatterns = [
    # path('',views.home, name ='home'),
    path('',views.DesignerList.as_view(), name='designer'),
    path('create',views.DesignerCreate.as_view(), name='create'),
    path('delete/<int:pk>',views.DesignerDelete.as_view(), name='delete'),
    path('update/<int:pk>',views.DesignerUpdate.as_view(), name='update'),

]

 ]

home.html

<a href="{% url 'delete' pk=d.pk %}">
        <button>
           삭제
        </button>
    </a>

delete.html

- 확인 메시쥐

<form action="" method="post">{% csrf_token %}
    <p>진짜 삭제할건가요? "{{ object }}"?</p>
    <input type="submit" value="삭제" />
</form>

 

4. Update (게시물 수정)

- create와 유사하고, delete 처럼 pk 값을 넘겨주어야한다.

views.py

#Update(게시물 수정)
class DesignerUpdate(UpdateView):
    model = models.Designer
    fields = ['image', 'name', 'adress', 'description',]
    template_name='update.html'
    success_url='/' # or reverse_lazy('designer') url 이름

    # def form_valid(self, form):
    #     designer = form.save(commit=False)
    #     designer.adress =form.cleaned_data['image']
        
    #     designer.save()
    #     return super().form_valid(form)

urls.py

from django import urls
from django.urls import path

from . import views

urlpatterns = [
    # path('',views.home, name ='home'),
    path('',views.DesignerList.as_view(), name='designer'),
    path('create',views.DesignerCreate.as_view(), name='create'),
    path('delete/<int:pk>',views.DesignerDelete.as_view(), name='delete'),
    path('update/<int:pk>',views.DesignerUpdate.as_view(), name='update'),

]

home.html

{% extends 'base.html' %}
<br>
{% block content %}
<br>
<br>
<h3> 여기는 홈 화면 템플릿 변수를 이용해 화면에 출력했지롱 </h3>

{% for d in designer %}
    <div>
    {% if d.image %}
        <img src = '{{ d.image.url }}' hegiht = 150 width = 150>
    {% endif %}
    
    <h5>{{ d.name }} </h5>
    <h5>{{ d.adress }} </h5>
    <h5>{{ d.description }} </h5>
    <a href="{% url 'delete' pk=d.pk %}">
        <button>
           삭제
        </button>
    </a>

    <a href="{% url 'update' pk=d.pk %}">
        <button>
           수정
        </button>
    </a>
    </div>

    
    
{% endfor %}

<a href="{% url 'create'%}">
<button>
    디자이너 생성
</button>
</a>
{% endblock %}

 

 

update.html

{{ object }} 수정 페이지 <br>
<form action="" method="post"  enctype="multipart/form-data">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Update" />
</form>

{{