본문 바로가기
Django

[Django] 장고 게시글 읽기/삭제 기능 만들기 #####

by kming 2023. 5. 25.

게시글을 작성 했으니까 읽어와야겠죠~? 데이터베이스에 있는 내용들을 가져 와 보려고해요!

    1. 게시글 읽어오기
    <aside> 💡 데이터베이스에 있는 게시글을 읽어오려고 해요! 읽어오는 기능은 'GET'으로 작성 되는 점 기억하면서 작성 해 보도록 하겠습니다!게시글을 읽어오는 url은 우리가 이미 작성을 해 놓았습니다.아래의 tweet함수에서, 요청이 "GET"으로 들어오는 부분을 같이 수정 해 보려고 합니다!로그인이 된 상태에서 게시글을 읽어와야 하니까, 로그인 사용자를 검증 한 후에 TweetModel을 불러 주는 기능을 작성 해 주도록 할게요!
    # tweet/views.py
    
    def tweet(request):
        if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기
            user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기
            if user:  # 로그인 한 사용자라면
                **all_tweet = TweetModel.objects.all().order_by('-created_at')
                return render(request, 'tweet/home.html', {'tweet': all_tweet})**
            else:  # 로그인이 되어 있지 않다면
                return redirect('/sign-in')
        elif request.method == 'POST':  # 요청 방식이 POST 일때
            user = request.user  # 현재 로그인 한 사용자를 불러오기
            my_tweet = TweetModel()  # 글쓰기 모델 가져오기
            my_tweet.author = user  # 모델에 사용자 저장
            my_tweet.content = request.POST.get('my-content', '')  # 모델에 글 저장
            my_tweet.save()
            return redirect('/tweet')
    
    • all_tweet = TweetModel.objects.all().order_by('-created_at') → TweetModel을 created_at의 역순으로 불러오는 코드입니다. 타임라인은 최신 글이 가장 상단에 있기 때문에 생성된 시간의 역순으로 불러왔어요!
    • return render(request, 'tweet/home.html', {'tweet': all_tweet}) → 처음보는 형식이지만, tweet/home.html을 화면에 띄우면서 {'tweet':all_tweet} 라는 데이터를 화면에 전달한다는 애기에요!
  • tweet 함수를 아래의 굵은 색 글씨로 표시 된 부분과 같이 수정 해 주세요.
  • # tweet/views.py def tweet(request): if request.method == 'GET': # 요청하는 방식이 GET 방식인지 확인하기 user = request.user.is_authenticated # 사용자가 로그인이 되어 있는지 확인하기 if user: # 로그인 한 사용자라면 return render(request, 'tweet/home.html') else: # 로그인이 되어 있지 않다면 return redirect('/sign-in') elif request.method == 'POST': # 요청 방식이 POST 일때 user = request.user # 현재 로그인 한 사용자를 불러오기 my_tweet = TweetModel() # 글쓰기 모델 가져오기 my_tweet.author = user # 모델에 사용자 저장 my_tweet.content = request.POST.get('my-content', '') # 모델에 글 저장 my_tweet.save() return redirect('/')
  • tweet앱의 views.py를 열어서 tweet 함수를 수정 해 주도록 할게요!
  • 게시글 쓰기를 만들었으니, 게시글 읽기를 만들어 보도록 하겠습니다!
  • 아까 우리가 작성 했었던 http://127.0.0.1:8000/tweet 이 바로 그 주소입니다. 앞서 얘기했던 대로 같은 주소에서 하는 일이 여러가지 인 것이죠.
  • </aside>
    1. 읽어온 게시글 화면에 노출시키기
    바로 전 단계에서 return render(request, 'tweet/home.html', {'tweet': all_tweet}) 부분을 통해서 읽어온 게시물을 tweet/home.html로 전달했어요!templates 의 tweet 폴더 내부에 작성 된 home.html를 열어주세요!(<hr> 태그를 찾으면 빠르게 찾을 수 있습니다!)이 곳에다가 작성자, 작성 된 내용, 작성 된 시간 을 적어 주려고 합니다.
    • 코드 정렬하기 : control(또는 command) + alt(또는 option) + L
    • [코드스니펫] templates/tweet/home.html 작성된 글이 나오는 곳
    • {% for tw in tweet %} <div class="col-md-12 mb-2"> <div class="card"> <div class="card-body"> <div class="media"> <div class="media-body"> <h5 class="mt-0">{{ tw.content }}</h5> </div> <div style="text-align: right"> <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span> </div> </div> </div> </div> </div> {% endfor %}
    <!-- templates/tweet/home.html -->
    <hr>
    <!-- 작성 된 글이 나오는 곳 -->
    <div class="row">
        **{% for tw in tweet %}**
            **<div class="col-md-12 mb-2">
                <div class="card">
                    <div class="card-body">
                        <div class="media">
                            <div class="media-body">
                                <h5 class="mt-0">{{ tw.content }}</h5>
                            </div>
                            <div style="text-align: right">
                                <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        {% endfor %}**
    </div>
    
    • python의 for문과 비슷한 형태의 for문이 있어요!
    • views.py에서 넘겨 준 TweetModel이 '리스트'로 전달 되기 때문에 반복문을 사용해서 출력 해 줄 수 있어요!
    • 각 리스트 하나의 요소는 글쓰기 모델 하나이고, 그 안에 포함된 content, author, created_at 등의 요소들을 뽑아 줄 수 있어요.
    위의 내용을 적고 난 후에 다시 http://127.0.0.1:8000/tweet 로 접속 해 보면, 아래와 같이 글들이 잘 나오는 것을 보실 수 있습니다
  • 위의 코드를 아래와 같이 수정 해 주세요! (전부 쓰기 어려우니, 코드를 복사 하는 것도 방법이에요~!)
  • <!-- templates/tweet/home.html --> <hr> <!-- 작성 된 글이 나오는 곳 --> <div class="row"> <div class="col-md-12"> <div class="card"> <div class="card-body"> <div class="media"> <div class="media-body"> <h5 class="mt-0">Media heading</h5> <p>Will you do the same for me? It's time to face the music I'm no longer your muse. Heard it's beautiful, be the judge and my girls gonna take a vote. I can feel a phoenix inside of me. Heaven is jealous of our love, angels are crying from up above. Yeah, you take me to utopia.</p> </div> </div> </div> </div> </div> </div>
  • 그 중에서, 작성된 글이 나오는 곳을 수정 해 주려고 해요. 아래와 같은 부분의 코드를 찾아주세요.
  • html에서 이 데이터를 어떻게 사용 할 것인지 한번 작성 해 보도록 할게요!
    1. 글 삭제하기
    <aside> 💡 게시글은 각각의 고유한 게시글 id가 있습니다! 이 id 번호를 사용해서 '어떤 게시글' 을 지울지 판단 해 줄 수 있어요! 사용자를 고유하게 판별하기 위해서 id 가 필요하듯이, 게시글에도 id 번호가 있습니다! 이 점을 유의해서 생각하고 삭제기능을 같이 만들어볼게요~!삭제 할 기능을 추가 할 url은 http://127.0.0.1:8000/tweet/delete/게시글의id 입니다!
    • 게시글 삭제 view 만들기tweet앱의 views.py를 열어서 아래의 코드를 추가 해 주세요!
      # tweet/views.py
      from django.contrib.auth.decorators import login_required
      
      @login_required
      def delete_tweet(request, id):
          my_tweet = TweetModel.objects.get(id=id)
          my_tweet.delete()
          return redirect('/tweet')
      
      자세히 보면, 지금까지의 view함수와 다르죠~? 함수의 인자에 request 외에 id 가 추가되었습니다!
    • 이 id는 게시글 고유의 id로써 게시글을 구분 하는 데에 사용 할 변수에요!
    • 로그인 한 사용자만 접근이 가능 해야 하기 때문에 login_required 기능을 사용 해 줄 거에요. login_required 를 views.py 가장 위에 추가 해 주세요.
    • 게시글을 삭제 할 수 있도록 해 주는 기능을 만들겠습니다
    • 게시글 삭제 url 만들기이제 이 함수를 url과 연결 시켜 주도록 하겠습니다
      # tweet/urls.py
      
      from django.urls import path
      from . import views
      
      urlpatterns = [
          path('', views.home, name='home'),
          path('tweet/', views.tweet, name='tweet'),
          **path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),**
      ]
      
      • tweet/delete/int:id 는, tweet/delete/123 과 같이 맨 뒷자리에 숫자가 온다는 얘기이고, 이 숫자는 id에 담겨져 delete_tweet에 전달이 됩니다.
      • 이 id를 views.py의 delete_tweet(request,id) 에서 매개변수로 받아 사용을 할 수 있는 것 입니다.
    • tweet앱의 urls.py를 열어 주시고 아래에 보이는 굵은 글자로 표시 된 코드를 추가 해 주세요
    • 게시글을 삭제 할 tweet앱의 views.py의 delete_tweet 함수를 만들었어요!
    • home.html에 게시글 삭제 url 넣어주기이제 10번 게시물을 삭제하고 싶을 때에는, /tweet/delete/10 이라고 요청 하면 됩니다.templates 폴더의 tweet내에 작성 되어있는 home.html을 열고, 아래에 굵은 표시로 된 부분을 추가 해 주세요
      • [코드스니펫] templates/tweet/home.html 글 삭제하기
      • {% if tw.author == user %} <div style="text-align: right"> <a href="/tweet/delete/{{ tw.id }}"> <span class="badge rounded-pill bg-danger">삭제</span> </a> </div> {% endif %} <div style="text-align: right"> <a href="#"> <span class="badge rounded-pill bg-success">보기</span> </a> </div>
      <!-- templates/tweet/home.html -->
      ... 생략 
      
      <!-- 작성 된 글이 나오는 곳 -->
      <div class="row">
          {% for tw in tweet %}
              <div class="col-md-12 mb-2">
                  <div class="card">
                      <div class="card-body">
                          **{% if tw.author == user %}
                          <div style="text-align: right">
                              <a href="/tweet/delete/{{ tw.id }}">
                                  <span class="badge rounded-pill bg-danger">삭제</span>
                              </a>
                          </div>
                          {% endif %}
      										<div style="text-align: right">
      										    <a href="#">
      										        <span class="badge rounded-pill bg-success">보기</span>
      										    </a>
      										</div>**
                          <div class="media">
                              <div class="media-body">
                                  <h5 class="mt-0">{{ tw.content }}</h5>
                              </div>
                              <div style="text-align: right">
                                  <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                              </div>
                          </div>
                      </div>
                  </div>
              </div>
          {% endfor %}
      </div>
      
      ... 생략
      
      • 이 게시글의 author (글쓴이) 와, 로그인 한 사용자가 같을 때에만 '삭제' 버튼이 나타납니다
      • 삭제 버튼은 /tweet/delete/tw.id 로 연결이 되는데, 이 tw.id는 게시글의 고유 id값입니다!
      이제 화면을 새로고침 해 주면, '삭제' 버튼과 '보기'버튼이 추가가 되어 있는 모습을 볼 수 있어요
        1. 게시글 읽어오기
        <aside> 💡 데이터베이스에 있는 게시글을 읽어오려고 해요! 읽어오는 기능은 'GET'으로 작성 되는 점 기억하면서 작성 해 보도록 하겠습니다!게시글을 읽어오는 url은 우리가 이미 작성을 해 놓았습니다.아래의 tweet함수에서, 요청이 "GET"으로 들어오는 부분을 같이 수정 해 보려고 합니다!로그인이 된 상태에서 게시글을 읽어와야 하니까, 로그인 사용자를 검증 한 후에 TweetModel을 불러 주는 기능을 작성 해 주도록 할게요!
        # tweet/views.py
        
        def tweet(request):
            if request.method == 'GET':  # 요청하는 방식이 GET 방식인지 확인하기
                user = request.user.is_authenticated  # 사용자가 로그인이 되어 있는지 확인하기
                if user:  # 로그인 한 사용자라면
                    **all_tweet = TweetModel.objects.all().order_by('-created_at')
                    return render(request, 'tweet/home.html', {'tweet': all_tweet})**
                else:  # 로그인이 되어 있지 않다면
                    return redirect('/sign-in')
            elif request.method == 'POST':  # 요청 방식이 POST 일때
                user = request.user  # 현재 로그인 한 사용자를 불러오기
                my_tweet = TweetModel()  # 글쓰기 모델 가져오기
                my_tweet.author = user  # 모델에 사용자 저장
                my_tweet.content = request.POST.get('my-content', '')  # 모델에 글 저장
                my_tweet.save()
                return redirect('/tweet')
        
        • all_tweet = TweetModel.objects.all().order_by('-created_at') → TweetModel을 created_at의 역순으로 불러오는 코드입니다. 타임라인은 최신 글이 가장 상단에 있기 때문에 생성된 시간의 역순으로 불러왔어요!
        • return render(request, 'tweet/home.html', {'tweet': all_tweet}) → 처음보는 형식이지만, tweet/home.html을 화면에 띄우면서 {'tweet':all_tweet} 라는 데이터를 화면에 전달한다는 애기에요!
      • tweet 함수를 아래의 굵은 색 글씨로 표시 된 부분과 같이 수정 해 주세요.
      • # tweet/views.py def tweet(request): if request.method == 'GET': # 요청하는 방식이 GET 방식인지 확인하기 user = request.user.is_authenticated # 사용자가 로그인이 되어 있는지 확인하기 if user: # 로그인 한 사용자라면 return render(request, 'tweet/home.html') else: # 로그인이 되어 있지 않다면 return redirect('/sign-in') elif request.method == 'POST': # 요청 방식이 POST 일때 user = request.user # 현재 로그인 한 사용자를 불러오기 my_tweet = TweetModel() # 글쓰기 모델 가져오기 my_tweet.author = user # 모델에 사용자 저장 my_tweet.content = request.POST.get('my-content', '') # 모델에 글 저장 my_tweet.save() return redirect('/')
      • tweet앱의 views.py를 열어서 tweet 함수를 수정 해 주도록 할게요!
      • 게시글 쓰기를 만들었으니, 게시글 읽기를 만들어 보도록 하겠습니다!
      • 아까 우리가 작성 했었던 http://127.0.0.1:8000/tweet 이 바로 그 주소입니다. 앞서 얘기했던 대로 같은 주소에서 하는 일이 여러가지 인 것이죠.
      • </aside>
        1. 읽어온 게시글 화면에 노출시키기
        바로 전 단계에서 return render(request, 'tweet/home.html', {'tweet': all_tweet}) 부분을 통해서 읽어온 게시물을 tweet/home.html로 전달했어요!templates 의 tweet 폴더 내부에 작성 된 home.html를 열어주세요!(<hr> 태그를 찾으면 빠르게 찾을 수 있습니다!)이 곳에다가 작성자, 작성 된 내용, 작성 된 시간 을 적어 주려고 합니다.
        • 코드 정렬하기 : control(또는 command) + alt(또는 option) + L
        • [코드스니펫] templates/tweet/home.html 작성된 글이 나오는 곳
        • {% for tw in tweet %} <div class="col-md-12 mb-2"> <div class="card"> <div class="card-body"> <div class="media"> <div class="media-body"> <h5 class="mt-0">{{ tw.content }}</h5> </div> <div style="text-align: right"> <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span> </div> </div> </div> </div> </div> {% endfor %}
        <!-- templates/tweet/home.html -->
        <hr>
        <!-- 작성 된 글이 나오는 곳 -->
        <div class="row">
            **{% for tw in tweet %}**
                **<div class="col-md-12 mb-2">
                    <div class="card">
                        <div class="card-body">
                            <div class="media">
                                <div class="media-body">
                                    <h5 class="mt-0">{{ tw.content }}</h5>
                                </div>
                                <div style="text-align: right">
                                    <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            {% endfor %}**
        </div>
        
        • python의 for문과 비슷한 형태의 for문이 있어요!
        • views.py에서 넘겨 준 TweetModel이 '리스트'로 전달 되기 때문에 반복문을 사용해서 출력 해 줄 수 있어요!
        • 각 리스트 하나의 요소는 글쓰기 모델 하나이고, 그 안에 포함된 content, author, created_at 등의 요소들을 뽑아 줄 수 있어요.
        위의 내용을 적고 난 후에 다시 http://127.0.0.1:8000/tweet 로 접속 해 보면, 아래와 같이 글들이 잘 나오는 것을 보실 수 있습니다
      • 위의 코드를 아래와 같이 수정 해 주세요! (전부 쓰기 어려우니, 코드를 복사 하는 것도 방법이에요~!)
      • <!-- templates/tweet/home.html --> <hr> <!-- 작성 된 글이 나오는 곳 --> <div class="row"> <div class="col-md-12"> <div class="card"> <div class="card-body"> <div class="media"> <div class="media-body"> <h5 class="mt-0">Media heading</h5> <p>Will you do the same for me? It's time to face the music I'm no longer your muse. Heard it's beautiful, be the judge and my girls gonna take a vote. I can feel a phoenix inside of me. Heaven is jealous of our love, angels are crying from up above. Yeah, you take me to utopia.</p> </div> </div> </div> </div> </div> </div>
      • 그 중에서, 작성된 글이 나오는 곳을 수정 해 주려고 해요. 아래와 같은 부분의 코드를 찾아주세요.
      • html에서 이 데이터를 어떻게 사용 할 것인지 한번 작성 해 보도록 할게요!
        1. 글 삭제하기
        <aside> 💡 게시글은 각각의 고유한 게시글 id가 있습니다! 이 id 번호를 사용해서 '어떤 게시글' 을 지울지 판단 해 줄 수 있어요! 사용자를 고유하게 판별하기 위해서 id 가 필요하듯이, 게시글에도 id 번호가 있습니다! 이 점을 유의해서 생각하고 삭제기능을 같이 만들어볼게요~!삭제 할 기능을 추가 할 url은 http://127.0.0.1:8000/tweet/delete/게시글의id 입니다!
        • 게시글 삭제 view 만들기tweet앱의 views.py를 열어서 아래의 코드를 추가 해 주세요!
          # tweet/views.py
          from django.contrib.auth.decorators import login_required
          
          @login_required
          def delete_tweet(request, id):
              my_tweet = TweetModel.objects.get(id=id)
              my_tweet.delete()
              return redirect('/tweet')
          
          자세히 보면, 지금까지의 view함수와 다르죠~? 함수의 인자에 request 외에 id 가 추가되었습니다!
        • 이 id는 게시글 고유의 id로써 게시글을 구분 하는 데에 사용 할 변수에요!
        • 로그인 한 사용자만 접근이 가능 해야 하기 때문에 login_required 기능을 사용 해 줄 거에요. login_required 를 views.py 가장 위에 추가 해 주세요.
        • 게시글을 삭제 할 수 있도록 해 주는 기능을 만들겠습니다
        • 게시글 삭제 url 만들기이제 이 함수를 url과 연결 시켜 주도록 하겠습니다
          # tweet/urls.py
          
          from django.urls import path
          from . import views
          
          urlpatterns = [
              path('', views.home, name='home'),
              path('tweet/', views.tweet, name='tweet'),
              **path('tweet/delete/<int:id>', views.delete_tweet, name='delete-tweet'),**
          ]
          
          • tweet/delete/int:id 는, tweet/delete/123 과 같이 맨 뒷자리에 숫자가 온다는 얘기이고, 이 숫자는 id에 담겨져 delete_tweet에 전달이 됩니다.
          • 이 id를 views.py의 delete_tweet(request,id) 에서 매개변수로 받아 사용을 할 수 있는 것 입니다.
        • tweet앱의 urls.py를 열어 주시고 아래에 보이는 굵은 글자로 표시 된 코드를 추가 해 주세요
        • 게시글을 삭제 할 tweet앱의 views.py의 delete_tweet 함수를 만들었어요!
        • home.html에 게시글 삭제 url 넣어주기이제 10번 게시물을 삭제하고 싶을 때에는, /tweet/delete/10 이라고 요청 하면 됩니다.templates 폴더의 tweet내에 작성 되어있는 home.html을 열고, 아래에 굵은 표시로 된 부분을 추가 해 주세요
          • [코드스니펫] templates/tweet/home.html 글 삭제하기
          • {% if tw.author == user %} <div style="text-align: right"> <a href="/tweet/delete/{{ tw.id }}"> <span class="badge rounded-pill bg-danger">삭제</span> </a> </div> {% endif %} <div style="text-align: right"> <a href="#"> <span class="badge rounded-pill bg-success">보기</span> </a> </div>
          <!-- templates/tweet/home.html -->
          ... 생략 
          
          <!-- 작성 된 글이 나오는 곳 -->
          <div class="row">
              {% for tw in tweet %}
                  <div class="col-md-12 mb-2">
                      <div class="card">
                          <div class="card-body">
                              **{% if tw.author == user %}
                              <div style="text-align: right">
                                  <a href="/tweet/delete/{{ tw.id }}">
                                      <span class="badge rounded-pill bg-danger">삭제</span>
                                  </a>
                              </div>
                              {% endif %}
          										<div style="text-align: right">
          										    <a href="#">
          										        <span class="badge rounded-pill bg-success">보기</span>
          										    </a>
          										</div>**
                              <div class="media">
                                  <div class="media-body">
                                      <h5 class="mt-0">{{ tw.content }}</h5>
                                  </div>
                                  <div style="text-align: right">
                                      <span style="font-size: small">{{ tw.author.username }}-{{ tw.created_at|timesince }} 전</span>
                                  </div>
                              </div>
                          </div>
                      </div>
                  </div>
              {% endfor %}
          </div>
          
          ... 생략
          
          • 이 게시글의 author (글쓴이) 와, 로그인 한 사용자가 같을 때에만 '삭제' 버튼이 나타납니다
          • 삭제 버튼은 /tweet/delete/tw.id 로 연결이 되는데, 이 tw.id는 게시글의 고유 id값입니다!
          이제 화면을 새로고침 해 주면, '삭제' 버튼과 '보기'버튼이 추가가 되어 있는 모습을 볼 수 있어요
        • 게시물의 번호는, 각 게시물을 출력 할 때에 따라 오는 번호를 대입 해 주려고 합니다!
        • view와 url이 연결이 되었습니다!
      • 로그인이 되어야 삭제를 할 수 있도록 만들어 줄 것이구요, '내가 쓴 글' 만 삭제 할 수 있도록 조건을 붙여주려고 합니다.
      • </aside>
    • 게시물의 번호는, 각 게시물을 출력 할 때에 따라 오는 번호를 대입 해 주려고 합니다!
    • view와 url이 연결이 되었습니다!
  • 로그인이 되어야 삭제를 할 수 있도록 만들어 줄 것이구요, '내가 쓴 글' 만 삭제 할 수 있도록 조건을 붙여주려고 합니다.
  • </aside>