2022. 2. 22. 22:44ㆍ강의 정리/Django 기초
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!

Django 포스팅 좋아요 / 취소 구현하기
#insta/models.py
class Post(BaseModel):
author = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="my_post_set", on_delete=models.CASCADE)
# 중략
like_user_set = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="like_post_set", blank=True)
_필드의 related_name 옵션을 설정해주면, 쿼리셋시에 related_name을 이용하여 모델 객체를 불러올 수 있습니다.
ex)
기존 -> Post.objects.filter(author=user)
related_name -> user.my_post_set.all()
_related_name 이란
참조되는 테이블이 참조하는 테이블의 데이터를 가져오고 싶을 때 사용하는 이름을 정의하는 것입니다,
_ManyToManyField 란??
https://velog.io/@jiffydev/Django-9.-ManyToManyField-1
Django 9. ManyToManyField 1
1. Many-to-Many relationship 데이터베이스의 Many-to-Many relationship(이하 다대다 관계)는 처음 접하는 사람들을 힘들게 한다. 한 테이블의 여러 레코드가 다른 테이블의 여러 레코드와 연결되어 있는 관계
velog.io
_user.my_post_set은 유저가 작성한 포스팅에 접근하게 되고, user.like_post_set은 유저가 좋아요를 누른 포스팅에 접근하게 됩니다.
#insta/urls.py
urlpatterns = [
path('post/<int:pk>/like', views.post_like, name='post_like'),
path('post/<int:pk>/unlike', views.post_unlike, name='post_unlike'),
]
_ post_detail에 맞게 즉 포스팅 디테일뷰가 보여지는 url과 똑같이 매핑합니다.
#insta/views.py
# 포스팅 좋아요
@login_required
def post_like(request, pk):
post = get_object_or_404(Post, pk=pk)
post.user_like_set.add(request.user)
messages.success(request, f"{post}를 좋아합니다.")
redirect_url = request.META.get("HTTP_REFERER", "root") # HTTP_REFERER은 request 요청을 한 웹페이지의 주소를 보여준다.
# 만약 HTTP_REFERER가 없으면 root 주소를 가져온다.
return redirect(redirect_url)
# 포스팅 싫어요
@login_required
def post_unlike(request, pk):
post = get_object_or_404(Post, pk=pk)
post.user_like_set.remove(request.user)
messages.success(request, f"{post}를 좋아요를 취소합니다.")
redirect_url = request.META.get("HTTP_REFERER", "root") # HTTP_REFERER은 request 요청을 한 웹페이지의 주소를 보여준다.
# 만약 HTTP_REFERER가 없으면 root 주소를 가져온다.
return redirect(redirect_url)
_ request.META.get()이란??
request.META는 사용자의 IP 주소와 사용자 Agent(일반적으로 웹 브라우저의 이름과 버전)를 포함해 지정된 요청에 대해 사용할 수 있는 모든 HTTP 헤더가 들어있는 파이썬 딕셔너리 입니다.
출처 : https://yonghyunlee.gitlab.io/python/django-master-6/
템플릿단
#insta/templates/insta/_post_card.html
{% load bootstrap4 %}
{% load insta_tags %}
<div class="card">
<div class="card-header">
<img src= "{{ user.profile_url }}" style="width: 24px; height: 24px;"/>
<a href="{% url "insta:user_page" post.author.username %}" style="text-decoration:none">
{{ post.author }}
</a>
</div>
<div class="card-body">
{% if post.photo.url %}
<img src="{{ post.photo.url }}" style="width: 100%;"/>
{% endif %}
{% for tag in post.tag_set.all %}
<span class="badge badge-primary" style="color: #fff;
background-color: #007bff;">
#{{ tag.name }}
</span>
{% endfor %}
</div>
<div class="card-footer">
{% if post|is_like_user:user %}
<a href="{% url 'insta:post_unlike' post.pk %}" style="text-decoration:none">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FF0000" class="bi bi-heart-fill" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314z"/>
</svg>
</a>
{% else %}
<a href="{% url 'insta:post_like' post.pk %}" style="text-decoration:none">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#FF0000" class="bi bi-heart" viewBox="0 0 16 16">
<path d="m8 2.748-.717-.737C5.6.281 2.514.878 1.4 3.053c-.523 1.023-.641 2.5.314 4.385.92 1.815 2.834 3.989 6.286 6.357 3.452-2.368 5.365-4.542 6.286-6.357.955-1.886.838-3.362.314-4.385C13.486.878 10.4.28 8.717 2.01L8 2.748zM8 15C-7.333 4.868 3.279-3.04 7.824 1.143c.06.055.119.112.176.171a3.12 3.12 0 0 1 .176-.17C12.72-3.042 23.333 4.867 8 15z"/>
</svg>
</a>
{% endif %}
</div>
</div>
{{ post|is_like_user:user }}
_ Pipe(='|') 앞의 인자"post"는 tags.py 함수의 첫번째 인자로 넘어가고, "user"은 두번째 인자로 넘어갑니다.
아래 코드는 위 이해를 돕기위한 tags.py의 함수입니다.
@register.filter
def is_like_user(post, user):
# 해당 글의 is_like_user를 반환 하여줍니다.
return post.is_like_user(user)
_위 tags.py 함수는 모델단의 함수를 호출시켜줍니다.
# 만약 유저가 포스팅을 좋아한다면(=like_user_set에 유저 pk가 있다면) True를 반환
def is_like_user(self, user):
return self.like_user_set.filter(pk=user.pk).exists()
템플릿에서 -> tags.py 함수 호출 -> tags.py에서 model단 함수 호출
_ 아이콘을 지원해주는 사이트들
https://icons.getbootstrap.kr/
Bootstrap Icons
Bootstrap을 위한 공식 오픈 소스 SVG 아이콘 라이브러리
icons.getbootstrap.kr
Font Awesome
The world’s most popular and easiest to use icon set just got an upgrade. More icons. More styles. More Options.
fontawesome.com
_장고 템플릿 단에서 함수를 호출하고, 인자를 넘기고 싶다면 Django custom templates filter를
적용해야합니다.
https://docs.djangoproject.com/ko/4.0/howto/custom-template-tags/
How to create custom template tags and filters | Django 문서 | Django
Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate
docs.djangoproject.com
0. 해당 앱에 templatestags 라는 폴더를 만들어줍니다.
1. templatestags 폴더 안에 '__init__.py'와 'app이름_tags.py'를 만들어줍니다.
#insta/templatetags/insta_tags.py
from django import template
register = template.Library()
@register.filter
def is_like_user(post, user):
# 해당 글의 is_like_user를 반환 하여줍니다.
return post.is_like_user(user)
'강의 정리 > Django 기초' 카테고리의 다른 글
Django로 인스타그램 클론 코딩시 필요한 Skill (0) | 2022.03.12 |
---|---|
Django 인스타그램 follow 기능 구현 (0) | 2022.02.17 |
Django 인스타그램 Timeline sidebar 구현하기 (0) | 2022.02.17 |
Django 포스팅 쓰기 구현하기 (0) | 2022.02.14 |
Django 암호 수정 구현하기 (0) | 2022.02.08 |