Django - djangogirls-tutorial blog만들기 4, (views.py)

|

패스트캠퍼스 웹 프로그래밍 수업을 듣고 중요한 내용을 정리했습니다.
개인공부 후 자료를 남기기 위한 목적임으로 내용 상에 오류가 있을 수 있습니다.
이 포스팅에서는 djangogirls-tutorial을 보고 정리했습니다.


post_list view function

djangogitls-tutorial에서 view.py파일에서 def post_list함수의 경로 설정

import os

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string

from .models import Post


# view function은 항상 첫번째 인자로 request를 갖는다.
def post_list(request):
  # return HttpResponse('Post list입니다.')
  # 여기서 HttpResponse는 보통 우리가 보내는 모든 요청은 Http형식이고 이 Http는 응답을 보낸다.
  # 이때 HttpResponse는 Http응답을 보내기 위한 어떤 요청을 만들어낸다.

  # 즉 얘네도 결국 class이고, 이 class의 인스턴스 뒤에 문자열을 보내면 ('Post list~')
  # 이 문자열을 Http형태로 보내준다. (Http응답을 보내준다.)

  # 더 복잡한 연결을 하기 위해 app/templates/post_list.html을 만든다.



  ```python
  """
  first/
      first_file.txt
      second/
          second_file.txt
          third/
              module.py
              fourth/
                  fourth_file.txt

  modele.py에서
  0. 현재 경로
      os.path.abspath(__file__)
  1. third/ 폴더의 경로
      os.path.dirname(<현재경로>)
  1-1. second/ 폴더의 경로
      os.path.dirname(<third폴더의 경로>)
  2. second/second_file.txt의 경로
      os.path.join(<second폴더의 경로>, 'second_file.txt')
  3. fourth/ 폴더의 경로
      os.path.join(<현재경로>, 'fourth')
  4. fourth/fourth_file.txt의 경로
      os.path.join(<현재경로>, 'fourth', 'fourth_file.txt')

  -> def post_list에서 templates/blog/post_list.html파일의 내용을 읽어서 return 해주는 HttpResponse에 전달
  :param request:
  :return:
  """
  cur_file_path = os.path.abspath(__file__)
  # print(cur_file_path)
  third_file_path = os.path.dirname(cur_file_path)
  # print(third_file_path)
  second_file_path = os.path.dirname(third_file_path)
  # print(second_file_path)
  second_second_file_path = os.path.join(second_file_path, 'templates')
  # print(second_second_file_path)
  fourth_fourth_file_path = os.path.join(second_second_file_path, 'blog', 'post_list.html')
  print(fourth_fourth_file_path)

  html = open(fourth_fourth_file_path, 'rt').read()
  # 근데 매번 이렇게 해주는게 너무 번거로우니, settings.py에 TEMPLATES_DIR를 설정해준다.

  # 경로에 해당하는 html파일을 문자열로 로드해줌
  render_to_string : (path) -> template dir를 기준으로 가져온 특정 path값을 가져온다.

  # 근데 이때의 path는 setiings.py의 TEMPLATES안에 있는 path를 기준으로 해서 가져온다.
  # 가져온 문자열 돌려주기
  html = render_to_string('blog/post_list.html')

  # 특정 리퀘스트가 올떄 보통 http로 오고 여기로 응답을 보내는데 응답을 보내기 위한 무언가를 만들어준다.
  # 이렇게만 하면 Templates does not exist error가 나온다.

  # 왜냐하면 우리가 settings.py에 TEMPLATES_DIR를 만들어줬지만 얘가 어디를 참조해야 하는 지는 안 알려줬기 때문이다.
  # 그래서 다시 settings.py로 가서 설정을 해준다.
  return HttpResponse(html)  

  # 위의 두 줄을 한번에 줄여쓰는 방법
  # 결국 이 한줄만 사용하면 된다.
  return render(request, 'blog/post_list.html')
def post_list(request):
  posts = Post.objects.all()
  context = {
    'posts': posts, }

    # render는 주어진 인수를 사용해서
    # 여기서 1번째 인수: HttpResponse인스턴스
    # 2번째 인수: 문자열 (TEMPLATES['DIRS']를 기준으로 탐색할 템플릿 파일의 경로
    # 3번째 인수: 템플릿을 렌더링 할 때 사용할 객체의 모음
    return render(request, 'blog/post_list.html', context)

    # 여기서 render는 django.shortcuts 패키지에 있는 함수로서 첫번째 파라미터로 request를 받는다.
    return render(
        request=request,
        template_name='blog/post_list.html',
        context=context
    )
    # 둘 중 하나를 쓰면 된다.

post_detail view function

def post_detail(request, post_id):
    post = Post.objects.get(id=post_id)
    context = {
        'post':post
    }
    # return HttpResponse(post_id)

    # 숙제: post_detail view function이 올바르게 동작하는 html을 작성해서 결과보기
    return render(request, 'blog/post_detail.html', context)

post_create view function

def post_create(request):
    # print(request.GET.get('title'))

    if request.method == 'POST':
        # request의 method값이 'POST'일 경우 (POST method로 요청이 왔을경우)
        # request.POST에 있는 title, text값과
        # request.user에 있는 USER인스턴스(로그인한 유저)속성을 사용해서
        # 새 POST인스턴스를 생성
        # HttpResponse를 사용해 새로 생성된 인스턴스의 id, title, text정보를 출력(string)

        post = Post.objects.create(
            author=request.user,
            title=request.POST.get('title'),
            text=request.POST.get('text')
        )
        # return HttpResponse('id:{}, title:{}, text:{}'.format(post.id, post.title, post.text))
        # post.author는 객체

        # HTTP Redirection을 보낼 URL은 http://localhost:8000/ <- 도메인
        # '/'은 가장 최 하단
        # /로 시작하면, 절대경로, 절대경로의 시작은 도메인 :http://localhost:8000/
        # return HttpResponseRedirect('/')

        # post.delete()  # 이렇게 해도 지워진다.
        return redirect('post-list')

    else:
        return render(request, 'blog/post_create.html')

post_delete view function

def post_delete(request, post_id):
    # 연결되는 URL: localhost:8000/3/delete

    # 템플릿을 사용하지 않음(render하는 경우가 없음) -> 그냥 지우기만 하고 넘어가면 되니까 굳이 렌더링이 필요없다.

    # view function의 동작
    # 1. 오로지 request.method 가 'POST'일 때만 동작
    # (request.method가 'GET'일 때는 아무 동작도 안해도 됨

    # 2. request.method가 'POST'일때의 동작
    # post_id에 해당하는 Post인스턴스에서 delete()를 호출해서 DB에서 삭제
    # 이후 post-list(url name)로 redirect

    # post_list.html템플릿에서 for문을 순회하는 각 요소마다 form을 하나씩 추가
    # action은 post_delete() view function으로 연결되는 url
    # -> url태그를 사용한다, post_list.html에서 post_detail()로 연결하는 url생성법 참조

    # method는 POST
    # 내부에 있어야 할 input요소는 없음, 버튼 하나만 존재(삭제)
    # POST요청이므로 csrf_token태그를 각 form안에 사용할 것

    # 실제동작: post_list.html의 각 요소에 생성된 버튼을 클릭하면 이 함수가 실행되어야 함
    # breakpoint를 아래 리턴에 걸어놓은 후 request내의 내용을 확인

    # 먄약 request의 method가 POST라면
    if request.method == 'POST':
      # post_id에 해당하는 Post인스턴스에서 delete()함수를 호출
        post = Post.objects.get(id=post_id)
        post.delete()
        return redirect('post-list')
    return HttpResponse('post_delete view function')