"장고 추천기능"의 두 판 사이의 차이
(→추천버튼) |
|||
12번째 줄: | 12번째 줄: | ||
===혹은 이런 모델..=== | ===혹은 이런 모델..=== | ||
위처럼 해당 객체 아래에 다대다 관계를 만들어 연동할 수도 있지만, 다음과 같이 모델 자체를 따로 만드는 방법도 있다. | 위처럼 해당 객체 아래에 다대다 관계를 만들어 연동할 수도 있지만, 다음과 같이 모델 자체를 따로 만드는 방법도 있다. | ||
+ | |||
+ | (기본적으로 다대다 관계에선 참조테이블을 자동으로 만들지만, 직접 만들 수도 있다.(이유는 모르겠지만, 대부분 직접 만든다.)) | ||
복잡한 모델을 구현할 땐 다음과 같이 중간모델을 만들기도 한다. 바로 ManyToMany로 잇기보단, 다음과 같이 중간모델을 만드는 게 일반적이다.<syntaxhighlight lang="python"> | 복잡한 모델을 구현할 땐 다음과 같이 중간모델을 만들기도 한다. 바로 ManyToMany로 잇기보단, 다음과 같이 중간모델을 만드는 게 일반적이다.<syntaxhighlight lang="python"> |
2022년 5월 16일 (월) 09:11 판
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 마침
위 작업은 추천 데이터의 반영을 창을 새로고침으로써 수행했다. 실시간, 비동기 반영을 원하면 장고 실시간 추천 문서를 참고하도록 하자.