티스토리 뷰

1.함수 기반 뷰에서 쿼리셋을 적용하는법

내가 아는 방법은 다음과 같다.

  1. 템플릿의 form에서 inputname을 지정한다.
  1. 뷰에서 requestGET.get을 통해 요청에 있는 파라미터의 값을 가져온다.
  1. 그 값을 filter함수를 통해 걸러낸다.

View의 코드는 다음과 같아진다.

def post_list(request:HttpRequest):
#Post의 모든 오브젝트를 가져온다.
    qs = Post.objects.all()
#Request에서 검색어를 가져온다. form에서 input의 name에는 q라고 지정이 되어있다.
    q = request.GET.get("q")
# 검색어와 일치하는 단어가 들어간 게시물만 걸러서 보여준다.
    qs= qs.filter(message__contains=q)
    return render(request,"instagram/post_list.html",{"post_list":qs, "q":q})

위와 같이 작성하면, 검색어를 포함한 게시글만 보여지게 된다.

2.클래스 기반 List뷰에서 쿼리셋을 적용하는법

  • 함수기반 뷰에서는 컨텍스트가 있어서, 결과값을 원하는 이름으로 집어넣을 수 있었는데, 클래스 기반 뷰에서는 자동으로 처리되는 것들이 많아서, 어떻게 손을 대야할지 모르겠는 경우가 있다.
  • 특히 검색처리같은 경우, 쿼리셋을 조작해서 타입이 있는경우, 검색어가 있는경우를 다 조작해야하는데 어떡하지 라는 생각이 들었다.
  • 다른 기능들은 일단 제처두고, query_set을 어떻게 내마음대로 조작해서 템플릿에 넘겨줄 수 있는지 알아보자
  • 관련 공식문서를 읽어보는것도 좋다.

https://docs.djangoproject.com/en/4.2/ref/class-based-views/generic-display/#django.views.generic.list.ListView

  • 클래스 기반 뷰에서 쿼리셋을 원하는대로 만들기 위해서는 get_queryset메서드의 오버라이드(재정의)가 필요하다

다음과 같은 코드를 통해 위와 같은 뷰를 구성할 수 잏다.

class PostListView(LoginRequiredMixin, ListView):
    model = Post
    paginate_by = 10
    def get_queryset(self):
        qs = super().get_queryset()
        q=self.request.GET.get("q","")
        
        qs = qs.filter(message__contains=q)
        
        return qs
    

post_list = PostListView.as_view()

하지만, 이 쿼리를 실행해보면, 다른 페이지네이션으로 이동했을때, 검색어가 초기화되어, 페이지네이션이 의미가 없어지는 것을 볼 수 있다.

그래서 검색어를 넣어주기 위해 context를 조작하는 방법을 알아봤다.

공식문서를 보니까, 재정의하는 코드가 나와있더라

위와같이 컨텍스트에 새로운 값을 넣기 위해서, context를 부모클래스의 get_context_data함수를 통해 가져오고, 그 뒤에 context[키] = value 형태로 집어넣어서 context를 다시 반환한다.

그러면 검색어를 다음 페이지로 넘어가서도 저장해 놓을 수 있을 것이다.

하지만 문제가 발생했다.

다음페이지로 넘어가도 검색어 유지가 안되길래 url을 보니까, ?page=1 과 같이 page만 남아있는것을 볼 수있었다.

django-bootstrap5 공식문서를 참조해도 방법이 없길래 chat-gpt를 활용해서 물어보니, extra태그의 사용방법과, extra에서 템플릿 빌드인 필터를 이용해서 쿼리스트링을 추가할 수 있는 방법을 찾았다.

템플릿 코드는 다음과 같다.

{% extends 'instagram/layout.html' %} 
{% load bootstrap5 %} 
{% block title %}
  Instagram /Post List
{% endblock title %} 

{%block content %}
  <form action="" method="get">
    <input type="text" name="q" id="" value="{{ q }}" />
    <input type="submit" value="검색" />
  </form>
  <div class="d-grid gap-2">
    <a href="{% url 'instagram:post_new' %}" class="btn btn-primary mt-3 mb-3">새 포스팅</a>
  </div>

  <table class="table table-bordered table-hover">
    <tbody>
      {% for post in post_list %}
      <tr>
        <td>{{post.pk}}</td>
        <td>
          <a href="{{post.get_absolute_url}}"> {{post.message}} </a>
        </td>
        <td>
          {% if post.photo %}
          <img src="{{post.photo.url}}" alt="" width="150px" />
          {% else %} no Photo {% endif %}
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
  {{ page_obj }}
# 중요한 부분이 여기다. extra="q=검색어"의 형태로 파라미터에 값을 넣어야 하는데, 태그 내에서 
# 컨텍스트에 들어있는 값을 쓰기 위해서는 |add 와같은 필터를 사용해야 한다. 
{% bootstrap_pagination page_obj size="small" extra='q='|add:q justify_content="center"%} 
{% endblock content %}

https://docs.djangoproject.com/en/3.2/ref/templates/builtins/

결과는 다음과 같다.

이렇게 페이지가 넘어가도 유지되는 모습을 볼 수 있다.

chat gpt에 한 열번은 넘게 다시 물어본것 같다… 말을 지어내거나 하는경우도 있어서 더 헷갈렸는데, 점점 좁혀나가는 식으로 질문하니 결국 알려주긴 하더라


Uploaded by N2T

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함