본문 바로가기
django

2021.01.15_django hitcount 조회수

by 해맑은 코린이 2021. 1. 15.

2021.01.15_django hitcount 조회수_정리노트

 

ㅎㅇㅎㅇ ㄹㅇ 오랜만.... 개인프로젝트를 2020년 안에 하려고 하다가..학교..랑 미루기..절구절구..완성하고 우다다다 적으려다 Js 가 아직 너무 기초도 없고 아무것도 못하는것마느니 못해서.. 블로그로 다시 복귀... 자바스크립트도 이제 그냥 공부하면서 적어야겠음... 

 

쨋든 간만에 포스팅은 django 안에 있는 조회수 기능을 통해 조회수 구현하기!

 

 

먼저 pip install django hit-count 명령어를 통해 설치해주고, 

 

 

 

settings.py 에 있는 installed_apps hitcount 에도 등록 ㄱㄱ

 

 

다음으로 뷰 ㄱㄱ

 

 

기본적으로 클래스뷰에서 HitCountDetailView로 쉽게 사용할 수 있기 때문에, 나는 클래스형 뷰를 사용했다.

 

 

 

이렇게 HitCountDetailView 를 불러와주고, 

 

 

count_hit 옵션을 True로 주면 조회수 기능을 사용이 가능한데, 클래스형의 뷰를 쓸 때는 예전 포스팅에서 말했듯이 여러가지 내가 원하는 것들을 설정해줄 수 있다. 

 

model = Post 

먼저 이 해당 뷰를 사용하는 모델을 알려줘야겠지? 우리가 조회수, 디테일 페이지를 나타내는 Post 모델을 지정해준다.

 

template_name

우리가 상속받은 뷰들을 사용하려면, 템플릿을 연결시켜줘야 하는데, 장고에서 정해준 이름이 각각 있는데, 그대로 맞추어줘도 되고, 이 옵션을 사용해 내가 이 뷰에 대한 템플릿은 이거야! 라고 정해줄수도 있다. 그대로 해줘도 되는데, 나는 헷갈리기도 하고 이미 쓰고 있는 html이 있었기 때문에 detail.html 로 설정해주었음 ㅎㅁㅎ

 

context_object_name

디테일뷰를 쓰면 해당 pk값을 가진 Post 모델의 객체를 가져올텐데, 이거 또한 내가 원래 썼던 이름이 my_post 라 이 옵션도 적용해주었다. 다른 제너릭뷰, 예를 들어 리스트 뷰에 들어갈 객체 이름도 내가 마음대로 설정해서, 템플릿에서 적어 줄 수가 있다.

함수형에서 detail을 구현할 때, my_post = Post.objects.get(id=id) 해서 context로 가져왔었지!! 그거랑 같은거다.

 

 

나는 보통 내 마음대로 로직을 이리저리 짜는 함수형 뷰를 많이 쓰다보니, 클래스형에서는 내가 가져오고 싶은 것들을 적으려면, 규칙 같은 것들이 뷰마다 달라서 애를 많이 먹었다. 그래도 그만큼 복잡한 로직을 구현하지 않아도 되는 편이라 클래스형 뷰도 계속 써보면서 익혀야하긴 해야할 듯..

 

 

자 여기서 근데 나는 끝이 아님 .. 내 디테일뷰에는 댓글도 띄워줘야 하고, context로 가져가야 할 추가적인 데이터가 너무 많거든.. 그럴땐 또 써주는 방법이 있지!!

 

출처 - django 공식문서

 

 

 

어려운 얘기 같지만, 그냥 이 함수 옵션을 사용해서 추가적인 데이터들을 context로 리턴해서 들고 올 수 있단 말씀~!

get_conntext_data 라는 옵션 함수가 정해져 있는거기 때문에 그대로 함수 이름도 적어 주어야 해당 기능 사용 가능

 

 

출처 - django 공식 문서

 

그리고 이 옵션의 밑에 보면, 이런 노트가 있는데, 왜 이렇게 쓰는지 친절히 설명도 되어 있다. 

나대로 정리하자면, 일반적으로 get_context_data 라는 녀석은 상위 클래스의 컨텍스트 데이터를 현재 클래스의 컨텍스트 데이터와 병합을 하는데, 현재 자신의 클래스에서 이 동작을 유지하려면, super를 써서 자체 클래스를 호출해야 한다.

 

이게 뭐선 말이냐면, 이 함수를 쓰면 내가 현재 들고 오고 싶은 위치는 디테일뷰에서 들고 오고 싶은데, 일반적으로는 상위 클래스뷰에서 컨텍스트 데이터를 참조한다는 소리다. 그래서 내가 해당 디테일 뷰 자체에서 이 함수를 써서 추가 컨텍스트 데이타를 들고 오고 싶으면 super를 써란 말이다...

 

 

음 내가 설명해도 어렵군 .. 그래도 다시 풀어서 다시 생각해보면!!! 

 

 

 

 

나는 PostDetail 이라는 클래스형 뷰를 만들었는데, 여기서 추가적인 데이터를 들고오고 싶은데 이 함수를 쓰게 되면, 일반적으로 포스트 디테일을 참조하지 않고, 다른 상위 클래스의 데이터와 병합을 한다는 소리인 거 같음.

 

 

그치만 우리는 여기 자체에서 컨텍스트 데이터를 보내주고 싶잖어?

 

 

 

 

그러면 super 라는 메소드를 써서 바로 우리가 쓰고 싶은 자체 클래스를 들고온다!! 그래서 해당 함수를 self, **kwargs 로 파라미터로 들고와서 리턴을 해줄 수 있나봄..ㅇㅇ 쨋든 get_context_data 를 쓸 때는 슈퍼로 꼭 자체 클래스를 가지고 올 수 있게 해줍씨다.

 

 

 

그러고 중간에 우리가 들고 오고 싶은 데이터들을 적어주고 마지막으로 context를 리턴해주면 완성... 

 

어렵지만 ( 나한테만 그럴지도 )  이 기능을 알아 놓으면 다른 클래스형 뷰에도 써먹을게 많기 때문에 형식처럼 그냥 외워놔도 도움이 많이 될 것 같다 ㅎㅎ

 

 

자 나는 이렇게 내가 불러오고 싶은 데이터들을 이렇게 담아 주었다. 네비바에 띄워줄 카테고리 오브젝트들, 댓글과 대댓글 폼까지 이렇게 추가적으로 들고 왔다. 

 

 

 만약 , 조회수를 정렬하고 싶을 때는 ? 이렇게 적어주면 된다. 근데 나는 해당 디테일뷰에서 정렬하고 싶은 것이 아니라서 주석처리 했다. 

 

자 그러면 다른 뷰에서 이 오브젝트들을 들고와서 정렬해주고 싶을때?

또는 필요 없을 지라도, 조회수를 구현하기 위해서는 몇 단계가 더 남았다. 

 

 

모델로 ㄱㄱ!

 

 

모델에서도 해당 Post 모델에 HitcountMixin 상속이 필요하다. 

 

 

이렇게!! 상속해주면, 기본적인 조회수를 구현하기 위한, 모델에서 설정해줄 것은 끝난다. 

 

근데 나는 아까 다른 뷰에서 해당 오브젝트들을 조회수를 들고 와서 정렬해주고 싶다고 했잖음?

 

그래서 그 작업에 대한 옵션은 모델에서 주었다. 

 

 

먼저 GenericRelation 을 불러와주자.

 

 

이렇게 장고의 Hitcount 모델을 상속받아 정의를 해주면, 조회수 별로 우리가 해당 포스트의 오브젝트들을 필터링해서 들고 올 수 있는데, 

 

여기서 GenericRelation 이란,

포린키랑 비슷한 개념이라고 생각하면 되는데, 포린키는 모델과 모델의 관계를 정의하는 거라면, 이 옵션은 해당 포스트 모델의 오브젝트 인스턴스는 각각 Hitcount 에 대해 검색할 수 있는 hit_count_generic 속성이 생기는거라고 볼 수 있다. 

음... 어렵지만 내가 해석한 바로는 Post 모델에 HItcount 에 대한 것을 검색하고, 필터링할 수 있는  hit_count_generic 속성이 생긴 필드를 하나 만든다고 해석했다. 

그래서 안에 적어준 것들은, 우리가 해당 pk를 들고오는 필드와, 포린키를 썼을 때 썼던 related_name 과 같이 여기서는 related_query_name 으로 해당 필드를 정의해준다. 만약 일반 포린키를 정의하고 싶다면, content_type_field 옵션을 정해주면 된다. 

 

으어 어렵.. 더 자세한 설명은   공식문서  링크로 달아놓겠음.

 

이렇게 하면, 우리는 다른 뷰딴에서도 

 

index.views

 

이렇게 related_query_name 으로 적어서 정렬해줄 수 있음. 나는 가장 조회수가 높은 순으로 정렬해주고 싶기 때문에 - 를 사용하여 10개의 포스트 오브젝트들을 정렬해주었다.

 

 

후.. 자 이제 마지막으로 조회수를 템플릿상에서 띄워주자!

 

 

먼저 load 를 통해 태그들을 불러오고 within 을 이용하여, 7일 동안의 조회수를 띄워주었다. 

 

전체 옵션은 

 

{% get_hit_count for [object] %}

 

이 오브젝트에 대한 총 조회수를 가져온다. ( 여기서 내 오브젝트 이름은 my_post 이다. )

 

{% get_hit_count for [object] as [var] %}

 

해당 오브젝트에 대한 총 조회수를 지정해준 변수를 사용해서 들고 온다.

 

{% get_hit_count for [object] within ["days=1,minutes=30"] %}

 

특정 시간에 대하여 , 내 오브젝트의 조회수를 불러온다 ( 내가 사용한 방법 )

 

{% get_hit_count for [object] within ["days=1,minutes=30"] as [var] %}

 

특정 시간에 대한, 내 오브젝트의 조회수를 지정해준 변수를 사용해 들고 온다.

 

 

여기서 자신이 원하는 옵션으로 불러오면 될 것 같다! 

아참, 먼저 {% load hitcount_tags %} 를 통해 불러오는거 잊지말기!!!

 

 

헥헥.. 이제 마지막으로 

 

urls.py

 

뷰를 사용했으니 url 상에서 .as_view() 를 사용해 연결만 시켜주면 진짜 끝!!! 

 

참고로 *를 사용하면, 해당 경로에 있는 뷰에 대한 모든 함수들을 들고 올 수 있다. 뷰에서 함수 하나를 생성할 때 마다 다 불러와주지 않아도 됨 ㅇㅇ

 

 


잘 작동되나 확인해보자~!~!

detail.html

 

 

조회수 1로 잘 올라가고, 

index.html

 

 

모델에서 준 옵션 때문에 홈 화면에서도 10개가 잘 정렬 되어 있는 모습을 볼 수 있다! 

 

 

 

 


 

이제 최대한 매일매일 다시 포스팅 시작.... ㅠㅠㅠ 너무 오랫동안 안했더니 두서도 없고 뭔가 생각보다 알아볼 것도 많은 것 같다. 이제는..... 내가 너무 괴로웠던 유저커스텀에 대해서 슬슬 포스팅 해 볼 예정! 

그럼 오늘 포스팅 끝~! 

댓글