"장고 추천기능"의 두 판 사이의 차이
(→추천버튼) |
|||
53번째 줄: | 53번째 줄: | ||
적당한 곳에 다음과 같은 코드를 담는다.<syntaxhighlight lang="html+django"> | 적당한 곳에 다음과 같은 코드를 담는다.<syntaxhighlight lang="html+django"> | ||
<div class="text-center">추천한 사람 수:{{question.voter.count}}</div> | <div class="text-center">추천한 사람 수:{{question.voter.count}}</div> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | === 추천 여부에 따라 버튼 다르게 나타내기 === | ||
+ | <syntaxhighlight lang="html+django"> | ||
+ | {% if user in post.like_user_set.all %} <!--추천 모델 안에 유저가 있다면..--!> | ||
+ | <div class = 'like-btn active' ..... | ||
+ | {% else %} | ||
+ | <div class = 'like-btn' ..... | ||
+ | {% endif %} | ||
</syntaxhighlight> | </syntaxhighlight> | ||
2021년 7월 26일 (월) 22:05 판
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>
5.3 추천 여부에 따라 버튼 다르게 나타내기
{% if user in post.like_user_set.all %} <!--추천 모델 안에 유저가 있다면..--!>
<div class = 'like-btn active' .....
{% else %}
<div class = 'like-btn' .....
{% endif %}
6 마침
위 작업은 추천 데이터의 반영을 창을 새로고침으로써 수행했다. 실시간, 비동기 반영을 원하면 장고 실시간 추천 문서를 참고하도록 하자.