[Django] ORM with view

Jingi·2024년 3월 27일

Web

목록 보기
11/40
post-thumbnail

View 함수 이용

전체 게시글 조회

  • index.HTML

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <h1>Articles</h1>
      <a href="{% url "articles:new" %}">NEW</a>
      <hr>
      {% for article in articles %}
        <p>글 번호: {{ article.pk }}</p>
        <a href="{% url "articles:detail" article.pk %}">
          <p>글 제목: {{ article.title }}</p>
        </a>
        <p>글 내용: {{ article.content }}</p>
        <hr>
      {% endfor %}
    </body>
    </html>
    
  • views.py

    from .models import Article
    
    # Create your views here.
    def index(request):
        articles = Article.objects.all()
        context = {
            'articles': articles,
        }
        return render(request, 'articles/index.html', context)

단일 게시글 조회

  • url.py

    from django.urls import path
    from . import views
    
    app_name = 'articles'
    urlpatterns = [
        path('', views.index, name='index'),
        path('<int:pk>/', views.detail, name='detail'),
    ]
  • views.py

    def detail(request, pk):
        article = Article.objects.get(pk=pk)
        context = {
            'article': article,
        }
        return render(request, 'articles/detail.html', context)
  • detail.html

      <h1>Articles</h1>
      <a href="{% url "articles:new" %}">NEW</a>
      <hr>
      {% for article in articles %}
        <p>글 번호: {{ article.pk }}</p>
        <a href="{% url "articles:detail" article.pk %}">
          <p>글 제목: {{ article.title }}</p>
        </a>
        <p>글 내용: {{ article.content }}</p>
        <hr>
      {% endfor %}

Create를 구현하기 위한 View 함수

  • 사용자 입력 데이터를 받을 페이지 렌더링: new

  • 사용자가 입력한 데이터를 받아 DB에 저장 : create

  • new 기능
    - views.py

    def new(request):
    return render(request, 'articles/new.html')
    • new.html
      <h1>New</h1>
      <form action="{% url "articles:create" %}" method="POST">
        {% csrf_token %}
        <div>
          <label for="title">Title: </label>
          <input type="text" name="title" id="title">
        </div>
        <div>
          <label for="content">Content: </label>
          <textarea name="content" id="content"></textarea>
        </div>
        <input type="submit">
      </form>
      <hr>
      <a href="{% url "articles:index" %}">[back]</a>
    • create 기능
    def create(request):
        # print(request.GET)  # <QueryDict: {'title': ['제목'], 'content': ['내용']}>
        title = request.POST.get('title')
        content = request.POST.get('content')
    
        # 1
        # article = Article()
        # article.title = title
        # article.content = content
        # article.save()
    
        # 2
        article = Article(title=title, content=content)
        article.save()
    
        # 3
        # Article.objects.create(title=title, content=content)
        # return render(request, 'articles/create.html')
        return redirect('articles:detail', article.pk)

HTTP

  • 네트워크 상에서 데이터를 주고 받기위한 약속

HTTP request methods

  • 데이터(리소스)에 어떤 요청(행동)을 원하는지를 나타내는 것

'GET' Method

  • 특정 리소스를 조회하는 요청

'POST' Method

  • 특정 리소스에 변경(생성, 수정, 삭제)을 요구하는 요청(데이터는 전달할 때 HTTP Body에 담겨 보내짐)

HTTP response status code

  • 특정 HTTP 요청이 성공적으로 완료되었는지를 3자리 숫자로 표현하기로 약속한 것

CSRF(Cross-Site-Request-Forgery)

  • 사이트 간 요청 위조
  • DTL의 csrf_token 태그를 사용해 손쉽게 사용자에게 토큰 값 부여
  • 요청 시 토큰 값도 함께 서버로 전송될 수 있도록 하는 것
  • 겉모습이 똑같은 위조 사이트나 정상적이지 않은 요청에 대한 방어 수단

POST일 때만 Token 확인 이유?

  • POST는 단순 조회를 위한 GET과 달리 특정 리소스에 변경을 요구하는 의미와 기술적인 부분을 가지고 있기 때문

  • DB에 조작을 가하는 요청은 반드시 인증 수단이 필요

  • 데이터베이스에 대한 변경사항을 만드는 요청이기 때문에 토큰을 사용하여 최소한의 신원 확인을 하는 것

redirect

  • 게시글 작성 후 완료를 알리는 페이지를 응답하는 것
  • 데이터 저장 후 페이지를 주는 것이 아닌 다른 페이지로 사용자를 보내야 한다.
  • 클라이언트가 인자에 작성된 주소로 다시 요청을 보내도록 하는 함수

redirect 특징

  • 해당 redirect에서 클라이언트는 detail url로 요청을 다시 보내게 됨
  • 결과적으로 detail view 함수가 호출되어 detail view 함수의 반환 결과인 detail 페이지가 응답 받음
  • 결국 사용자는 게시글 작성 후 작성된 게시글의 detail 페이지로 이동하는 것으로 느끼게 되는 것
    def create(request):
        ....
        return redirect('articles:detail', article.pk)

Delete 기능 구현

  • views.py
    def delete(request, pk):
        # 몇번 글 삭제? -> 조회 먼저
        article = Article.objects.get(pk=pk)
        article.delete()
        return redirect('articles:index')
  • urls.py
    app_name = 'articles'
    urlpatterns = [
        path('<int:pk>/delete/', views.delete, name='delete'),
    ]

Update

  • Update를 구현하기 위해 2개의 view 함수가 필요

  • 사용자 입력 데이터를 받을 페이지를 렌더링 : edit

  • 사용자가 입력한 데이터를 받아 DB에 저장 : update

  • edit 기능 구현

    • views.py
    def edit(request, pk):
        article = Article.objects.get(pk=pk)
        context = {
            'article': article,
        }
        return render(request, 'articles/edit.html', context)
    • edit.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <h1>Edit</h1>
      <form action="{% url "articles:update" article.pk %}" method="POST">
        {% csrf_token %}
        <input type="text" name="title" value="{{ article.title }}">
        <textarea name="content">{{ article.content }}</textarea>
        <input type="submit">
      </form>
    </body>
    </html>
  • update 기능 구현

    • urls.py
    urlpatterns = [
        path('<int:pk>/update/', views.update, name='update'),
    ]
    • views.py
    def update(request, pk):
        # 몇번 글 수정? -> 조회 먼저
        article = Article.objects.get(pk=pk)
    
        title = request.POST.get('title')
        content = request.POST.get('content')
    
        article.title = title
        article.content = content
        article.save()
    
        return redirect('articles:detail', article.pk)
profile
데이터 분석에서 백엔드까지...

0개의 댓글