Django 인스타그램 follow 기능 구현

2022. 2. 17. 18:53강의 정리/Django 기초

반응형

출처 : https://www.inflearn.com/course/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%9E%A5%EA%B3%A0-%EC%9B%B9%EC%84%9C%EB%B9%84%EC%8A%A4/dashboard

 

장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!

 


 

Instagram Follow-Unfollow 기능 구현

#accounts/models.py

 

class User(AbstractUser):
	    follower_set = models.ManyToManyField("self", blank=True) # 현재 유저를 팔로우 하는 사람의 목록
    	# "self"를 통해서 대상을 User간의 관계로 지정할 수 있다.
    	following_set = models.ManyToManyField("self", blank=True) # 현재 유저가 팔로우 하는 사람의 목록

 

 


#accounts/urls.py

   urlpatterns = [
       re_path(r'^(?P<username>[\w.@+-]+)/follow/$', views.user_follow, name='user_follow'),  
       re_path(r'^(?P<username>[\w.@+-]+)/unfollow/$', views.user_unfollow, name='user_unfollow'),      
    ]

 

 


#accounts/views.py

# 팔로우 기능 
@login_required
def user_follow(request, username):
    follow_user = get_object_or_404(get_user_model(), username=username, is_active=True)
    
    # request.user -> follow_user를 팔로우 하려고 함.
    request.user.following_set.add(follow_user)
    # 반대로 팔로잉 된 유저의 follower_set에 현재 유저 추가
    follow_user.follower_set.add(request.user)

    messages.success(request, f"{follow_user}님을 팔로우 하였습니다.")
    redirect_url = request.META.get("HTTP_REFERER", "root") # HTTP_REFERER은 request 요청을 한 웹페이지의 주소를 보여준다.
    # 만약 HTTP_REFERER가 없으면 root 주소를 가져온다.
    return redirect(redirect_url)


# 언팔로우 기능
@login_required
def user_unfollow(request, username):
    unfollow_user = get_object_or_404(get_user_model(), username=username, is_active=True)

    # request.user -> follow_user를 팔로우 하려고 함.
    request.user.following_set.remove(unfollow_user)
    # 반대로 팔로잉 된 유저의 follower_set에 현재 유저 추가
    unfollow_user.follower_set.remove(request.user)

    messages.success(request, f"{unfollow_user}님을 언팔로우 하였습니다.")
    redirect_url = request.META.get("HTTP_REFERER", "root")
    return redirect(redirect_url)

 

 

 

https://docs.djangoproject.com/en/4.0/ref/request-response/


 

 

#insta/views.py


@login_required
def index(request):
    suggested_user_list = get_user_model().objects.all()\
        .exclude(pk=request.user.pk)\
        .exclude(pk__in=request.user.following_set.all())[:3] # 이미 팔로잉 하고 있는 유저들을 제외함.
        
    # 유저 본인 pk를 제외하고 나머지 유저가 suggested_user이다.
    return render(request, "insta/index.html", {
        "suggested_user_list" : suggested_user_list,
    })

 

 


템플릿 단

 

#insta/templates/insta/timeline_sidebar.html

<div class="card mb-2">
    <div class="card-header text-muted">
        Suggestions for you
    </div>
    <div class="card-body text-muted">
        {% for suggested_user in suggested_user_list %}
            {% include 'insta/timeline_sidebar_user_follow.html'%}
        {% empty %}
            추천 친구가 없습니다.
        {% endfor %} 
    </div>
</div>

 


#insta/templates/insta/timeline_sidebar_user_follow.html

<div class="d-flex">
    <div class="mr-3">
        <img src="{{ suggested_user.profile_url }}" style="width: 32px; height: 32px;" class="rounded-circle"/>}
    </div>
    <div class="p-2">
        {{ suggested_user.username }}
    </div>
    <div class="ml-auto">
        <a href="{% url "user_follow" suggested_user.username %}">Follow</a>
        <a href="{% url "user_unfollow" suggested_user.username %}">Unfollow</a>
    </div>
  </div>

 

 


#insta/templates/insta/index.html

{% extends "insta/layout.html" %}

{% block content %}
    <div class="container">
        <div class="row">
            <div class="col-sm-12">
                <a href="{% url 'insta:post_new' %}" class="btn btn-primary">새 포스팅 쓰기</a>             
            </div>
        </div>
        <div class="row">
            <div class="col-sm-8">     
                Timeline        
                <hr />
                {{ user.following_set.all }}   
            </div>
            <div class="col-sm-4">
                {% include "insta/timeline_sidebar.html" %}
            </div>
        </div>
    </div>
{% endblock %}

 

 

 

 


반응형