Python/python 클론코딩

인스타그램 클론코딩 (팔로우 / 언팔로우)

SeongWon 2020. 4. 20. 16:58
반응형

1. 팔로우 / 언팔로우 기능 구현

 

urls.py

re_path(r'^follow/(?P<follow>[ㄱ-힣a-zA-Z0-9-_.]*)/$', followingView, name='follow'),

뷰의 실행을 위해 url (패턴) 지정 

팔로우 / 언팔로우는 대상 유저의 user_id를 필요로 하기때문에 "[ㄱ-힣a-zA-Z0-9-_.]"로 패턴을 주어 어떤 경우의 글자 패턴이든 받아서 넘길 수 있도록 한다.

 

followingView.py

def followingView(request, follow):
    user = request.user
    cursor = connection.cursor()

    follow_button = "SELECT COUNT(*)"  # 방문된 유저가 로그인된 유저에게 팔로우가 되있는지 구분
    follow_button += " FROM following"
    follow_button += " WHERE user_id = (%s) AND following_id = (%s)"

    follow_button_result = cursor.execute(follow_button, (user.username, follow,))
    follow_button_datas = cursor.fetchall()

    if follow_button_datas[0][0] == 0:
        following_sql = "INSERT INTO following(user_id, following_id) "
        following_sql += " VALUES ((%s), (%s))"

        following_result = cursor.execute(following_sql, (user.username, follow,))
        is_follow = 0

    elif follow_button_datas[0][0] == 1:
        unfollowing_sql = "DELETE"
        unfollowing_sql += " FROM following"
        unfollowing_sql += " WHERE user_id = (%s) AND following_id = (%s)"

        unfollowing_result = cursor.execute(unfollowing_sql, (user.username, follow,))
        is_follow = 1

    follower_count_sql = "SELECT COUNT(user_id)"  # 타인의 팔로워 수 카운트
    follower_count_sql += " FROM following"
    follower_count_sql += " WHERE following_id = (%s)"

    follower_count_result = cursor.execute(follower_count_sql, (follow,))
    follower_count_datas = cursor.fetchall()
    followerCount = follower_count_datas[0][0]

    my_follower_count_sql = "SELECT COUNT(user_id)"  # 나의 팔로워 수 카운트
    my_follower_count_sql += " FROM following"
    my_follower_count_sql += " WHERE following_id = (%s)"

    my_follower_count_result = cursor.execute(my_follower_count_sql, (user.username,))
    my_follower_count_datas = cursor.fetchall()
    my_followerCount = my_follower_count_datas[0][0]



    following_count_sql = "SELECT COUNT(following_id)"  # 팔로잉 수 카운트
    following_count_sql += " FROM following"
    following_count_sql += " WHERE user_id = (%s)"

    following_count_result = cursor.execute(following_count_sql, (user.username,))
    following_count_datas = cursor.fetchall()
    followingCount = following_count_datas[0][0]

    connection.commit()
    connection.close()

    current_url = request.POST.get('current_url')
    current_url = current_url.split('/')


    return HttpResponse(json.dumps({"is_follow":is_follow , "followerCount": followerCount,
                                    "followingCount": followingCount, "list_page_user": current_url[4],
                                    "my_followerCount": my_followerCount, "user": user.username}), content_type="application/json")

 

post_list.html

{% if user.username != following_list.following_id %}
 {% if following_list.is_follow == 1 %}
  <button type="button" class="btn btn-light" id="follow_btn" onclick="follow(this, '{{ following_list.following_id }}')">팔로잉</button>
 {% endif %}
 {% if following_list.is_follow == 0 %}
  <button type="button" class="btn btn-primary" id="follow_btn" onclick="follow(this, '{{ following_list.following_id }}')">팔로우</button>
 {% endif %}
{% endif %}

팔로우 / 팔로잉 버튼에대한 html 코드의 일부분이다.

 

위 사진과 같이 로그인한 유저가 다른사람의 페이지에 load할 경우에는 로그아웃 버튼이 아닌 팔로우 혹은 이미 팔로우를 한 상태라면 팔로잉 버튼이 나타나게 된다. 

 

또한 이미 팔로우를 한 경우와 안한 경우에 따라서 팔로우 혹은 팔로잉 버튼이 따로따로 등장하게 된다.


※ 여기서 팔로우 기능을 View를  통해서만 구현이 가능하지만, 저 페이지의 일부분인 버튼 하나의 변화를 위해서 페이지 전체가 새롭게 load되어 굉장히 불필요한 과정이 발생한다.

 

일부만 새롭게 load되어 실행되는 Ajax를 통해서 구현을 해본다.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    function follow(eim,n) {
      $.ajax({
        url: "{% url 'instagram:follow' 1 %}". replace('1',n),
        data : {'csrfmiddlewaretoken': '{{ csrf_token }}', 'current_url': window.location.href },
        dataType: "json",
        type: "POST",
        success: function(response) {
          if (response.is_follow == 0) {
            $(eim).attr("class", "btn btn-light");                   
            $(eim).attr("onclick", "follow(this, '" + n + "')");     
            $(eim).text("팔로잉");                                   
            if (eim.id == "follow_btn_list"){
              $("#followerCounter").text(response.followerCount);
            }
            else if (eim.id == "follow_btn"){
              if (response.list_page_user == response.user){
                $("#followingCounter").text(response.followingCount);
              }
            }
          }
          else if (response.is_follow == 1) {
            $(eim).attr("class", "btn btn-primary");
            $(eim).attr("onclick", "follow(this, '" + n + "')");
            $(eim).text("팔로우");
            if (eim.id == "follow_btn_list"){
              $("#followerCounter").text(response.followerCount);
            }
            else if (eim.id == "follow_btn"){
              if (response.list_page_user == response.user){
                $("#followingCounter").text(response.followingCount);
              }
            }
          }
        },
        error: function(xhr) {
          alert("팔로우를 하는 과정에서 에러가 발생하였습니다.");
        }
      });
    }
</script>

현재 팔로우가 안돼있는 훈이를 팔로우해보면

follow 데이터베이스 테이블에 새롭게 추가된 것을 확인할 수 있다.

반응형