Django

Django MTV 사용하기 (RUD)

zhelddustmq 2024. 8. 14. 17:59

1. redirect

 

redirect : render함수로 새로운 html에 접근불가

  • html만 다른 템플릿으로 랜더링 했을뿐, 실제로 url이 이동해서 GET 요청을 보낸 것이 아님
  • redirect는 지정한 URL로 되돌리는 것
  • 우리가 웹 사이트를 이용하면서 많이 봐왔던 동작 방식
from django.shortcuts import render, redirect

...

def create(request):
  title = request.POST.get("title")
  content = request.POST.get("content")
  article = Article(title=title, content=content)
  article.save()
  return redirect("articles")

PRG (Post-Redirect-Get) 패턴: POST요청을 서버에서 처리하고 서버에서는 다른 주소로 Redirect하도록 응답하고 브라우저는 GET방식으로 서버를 호출하여 사용자의 요청이 반영된 것을 보여줌. 게시글 작성후 제출 버튼을 눌렀을 때 화면이 이동되지 않는다면 제출 버튼을 여러번 누를 수가 있는데, 그러면 중복된 게시글이 작성될 수 있음. PRG패턴을 사용하면 반복적인 POST호출을 막을 수 있고 사용자의 입장에서도 처리가 끝나고 처음 단계로 돌아간다는 느낌을 주게 됨.

 

상세페이지 조회하기

from django.urls import path
from . import views

urlpatterns = [
    path("", views.articles, name="articles"),
    path("<int:pk>/", views.article_detail, name="article_detail"),
    path("new/", views.new, name="new"),
    path("create/", views.create, name="create"),
    ...
]

<int:pk>로 어디로 들어왔는지 확인

 

# views.py
def article_detail(request, pk):
  article = Article.objects.get(pk=pk)
  context = {
      "article": article,
  }
  return render(request, "article_detail.html", context)
# article_detail.html
{% extends "base.html" %}

{% block content %}

    <h2>글 상세 페이지</h2>
    <p>제목: {{ article.title }}</p>
    <p>내용: {{ article.content }}</p>
    <p>작성일시: {{ article.created_at }}</p>
    <p>수정일시: {{ article.updated_at }}</p>

    <a href="{% url 'articles' %}">목록 보기</a>

{% endblock content %}

추가 작업

  • 게시글 작성후 상세페이지로 리다이렉트시키는 걸 구현
def create(request):
    title = request.POST.get("title")
    content = request.POST.get("content")
    article = Article(title=title, content=content)
    article.save()
    return redirect("article_detail", article.id)

 

 

글 삭제하기

  • 구현
    1. 글 삭제 로직을 진행하는 url 만들기
    2. 글 삭제하는 view 만들기
      • 삭제하고자 하는 글 가져오기
      • 글 삭제
      • 삭제한다음 이동할곳으로 redirect
    3. 글 삭제 버튼 만들어주기
# urls.py
path("<int:pk>/delete/", views.delete, name="delete"),
# views.py
def delete(request, pk):
  article = Article.objects.get(pk=pk)
  article.delete()
  return redirect("articles")

 

삭제 버튼 만들기

  • 삭제라는 것도 결국에는 데이터베이스를 조작하는 요청 !
  • 따라서→ form 사용
  • → POST 방식으로 요청해야함
{% extends "base.html" %}

{% block content %}

    <h2>글 상세 페이지</h2>
    <p>제목: {{ article.title }}</p>
    <p>내용: {{ article.content }}</p>
    <p>작성일시: {{ article.created_at }}</p>
    <p>수정일시: {{ article.updated_at }}</p>

    <a href="{% url 'articles' %}"><button>목록 보기</button></a>

    <hr>
    <form action="{% url 'delete' article.pk %}" method="POST">
        {% csrf_token %}
        <input type="submit" value="글삭제">
    </form>

{% endblock content %}

127.0.0.1:8000/articles/3/delete/ 를 직접 입력해서 들어가도 삭제됨!!!!

→ 왜?

→ 로직에 이상이 없으니까 !

  • 위 URL로 GET 요청이 들어오면
  • view에서 처리하니까
  • 삭제된다

요청방식이 POST인 경우만 삭제하도록 수정

def delete(request, pk):
  article = Article.objects.get(pk=pk)
  if request.method == "POST":
      article.delete()
      return redirect("articles")
  return redirect("article_detail", article.pk)

 

 

글 수정하기

    1. 글 수정하는 url 만들기
      • 수정할 글을 보여주는 url (articles/<pk>/edit/)
      • 글 수정을 처리할 url(articles/<pk>/update/)
    2. 글 수정하는 로직을 수행하는 view 만들기
      • 수정할 글을 보여주는 view (edit view)
      • 글 수정을 처리하는 view (update view)
    3. 글 수정을 수행하는 template 만들기 (edit.html)
    4. 글 수정 버튼 만들기 → detail 페이지에 만들어주기