장고 추천기능
둘러보기로 가기
검색하러 가기
1 개요
어떤 게시물을 추천하거나 북마크, 즐겨찾기 저장하는 등의 기능을 구현해보고자 한다. 셋 다 유사한 성격을 띄고 있어 같은 로직으로 짤 수 있다. 이름만 바꿔주면 작동한다.
게시글을 추천하거나 나중에 보기 위해 즐겨찾기하는 기능이 필요하다.
2 모델 수정
기존 글의 모델에 다음과 같이 필요한 속성을 추가한다.
voter = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True,null=True)
그런데, 이렇게 수정하고 DB에 반영하면 에러가 뜬다. 게시글의 작성자와 voter에 들어가는 사람이 둘 다 User모델을 참조하기 있기 때문에 User모델로 하위모델에 접근하려고 할 때 작성자를 기준으로 찾아야 할지, 추천자를 기준으로 찾아야 할지 정해지지 않기 때문이다.
=> 두 모델에 related_name 이라는 속성을 주어 User.옵션명.all 형태로 접근할 수 있다.
2.1 혹은 이런 모델..
위처럼 해당 객체 아래에 다대다 관계를 만들어 연동할 수도 있지만, 다음과 같이 모델 자체를 따로 만드는 방법도 있다.
복잡한 모델을 구현할 땐 다음과 같이 중간모델을 만들기도 한다. 바로 ManyToMany로 잇기보단, 다음과 같이 중간모델을 만드는 게 일반적이다.
class Post(models.Model):
...
like_user = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Like') # through는 연결할 모델을 의미한다.
class Like(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
writing = models.ForeignKey(모델명, on_delete=models.CASCADE)
create_at = models.DateTimeField(auto_add_now=True)
class Meta:
unique_together = (
('user','post')
)
모델을 위와 같이 짜면 좋아요를 날짜에 맞게 정렬할 수 있고, 기능을 추가하거나 수정하기 용이해진다. 때문에 굳이 위와 같이 새로운 모델을 만들어 사용한다.
3 url 추가
path('comment/vote/<int:question_id>/', views.vote, name='vote'),
4 뷰 추가
ManyToMany 필드는 add함수를 사용하여 추천인을 추가해야 한다.
@login_required(login_url='membership:login')
def vote_question(request, question_id):
question = get_object_or_404(Question, pk=question_id)
question_like, question_like_created = question.like_user.get_or_create(user=request.user)
#위 함수가 어떤 기능인지 제대로 파악해야겠다.
#question.voter.add(request.user)
if not question_like_created: # 생성된 게 아닌 경우.
question_like.delete() # 삭제한다.
return redirect('pool:detail', question_id=comment.answer.question.id)
동일한 글을 여러번 추천하더라도 추천수가 증가하진 않는다. 중복은 허락되지 않기 때문.
5 탬플릿 수정
5.1 추천버튼
<a href="{% url 'pool:vote' question.id%}" class="btn btn-primary">추천</a>
5.2 추천갯수 나타내기
적당한 곳에 다음과 같은 코드를 담는다.
<div class="text-center">추천한 사람 수:{{question.voter.count}}</div>