티스토리 뷰

이제 친구목록 페이지를 만든다.

이 페이지에는 나를 팔로우하는 사람, 내가 팔로우하는 사람을 출력하고, 원하는 사용자를 찾을 수 있도록 검색창으로 구성한다.

 

 

 

contents / views.py

친구목록 페이지를 구성하는 로직이다. 장고에서 제공하는 TemplateView를 상속받아 template_name 에 지정된 템플릿으로 렌더링할 수 있도록 한다.

그 전에 get_context_data 함수를 이용하여 기존에 보내지던 데이터에 필요한 정보를 더 추가해서 템플릿으로 넘겨준다. 여기서 필요한 정보는 내가 팔로우하는 사람들, 나를 팔로우하는 사람들에 대한 정보이다.

 

 

내가 팔로우하는 사용자 찾기

try:

내가 주체가 되는 FollowRelation 객체에서 followee 값(=> 내가 팔로우하는 사람들)을 모두 가져와서 context['followees']에 저장한다.

context['followees_ids']에 'followees'에 저장된 사용자들의 아이디를 저장한다. flat = True 값을 설정하여 id 값들을 리스트로 저장한다.

except:

나의 FollowRelation 객체가 없다면 내가 팔로우하는 사람은 없다는 것이므로 그냥 넘어간다.

 

나를 팔로우하는 사용자 찾기

filter(followee__in = [user]) : FollowRelation의 모든 객체 중에서 followee 필드 값에 나 자신(user)이 포함되는 FollowRelation 객체만 받아온다. 

select_related('follower') : 그리고 그 객체들 중에서 follower 값만 가져와서 나를 팔로우하는 사용자정보만 저장한다.

 

@method_decorator(login_required, name = 'dispatch')
class RelationView(TemplateView):
    template_name = 'relation.html'
    def get_context_data(self, **kwargs):
        context = super(RelationView, self).get_context_data(**kwargs)
        user = self.request.user

        try:
            followers = FollowRelation.objects.get(follower = user).followee.all()
            context['followees'] = followers
            context['followees_ids'] = list(followers.values_list('id', flat = True))

        except FollowRelation.DoesNotExist:
            pass 

        context['followers'] = FollowRelation.objects.select_related('follower').filter(followee__in = [user])
        return context

 

 

 

 

 

 

apis / views.py / UserInfoGetView

- 사용자를 검색할 때, 입력한 이름과 일치하는 사용자를 찾아 그에 대한 정보를 전달한다.

class UserInfoGetView(BaseView):
    def get(self, request):
        username = request.GET.get('username','').strip()
        try:
            user = User.objects.get(username = username)
        except user.DoesNotExist:
            self.response(message = "사용자를 찾을 수 없습니다.", status = 404)

        return self.response({'username':username, 'email':user.email, 'id':user.id})

 

 

 

 

 

templates / relation.html

 

1. 사용자 검색창

찾으려는 사용자 이름을 searchUserName에 저장한다.

검색 버튼을 누르면 searchUserName에 저장된 값에 대해서 일치하는 사용자를 찾아 #searchResult에 출력한다. 

 

 

2. 친구목록

 

(1) 나를 팔로우하는 사람들

RelationView에서 전달받은 context 의 followers 값을 사용한다.

 

{% if followers %} : 나를 팔로우하는 사람들(FollowRelation 객체)이 있다면

{% for myfollower in followers %} : 각각의 객체 정보를 가져와서 myfollower에 저장한다. 

 

{{myfollower.follower.username}} : 객체(myfollower)의 주체가 되는 (follower) 사용자의 이름을 출력한다. 즉, 그냥 날 팔로우하는 사람의 이름을 출력한다는 뜻이다.

 

{% if myfollower.follower.id in followees_ids %} : 만약 나를 팔로우하는 이 사람을 내가 팔로우하지 않은 경우, "팔로우" 버튼을 출력한다.

{% else %} : 나도 상대방을 팔로우 하고있는 경우, "언팔로우" 버튼을 출력한다.

 

 

 

(2) 내가 팔로우하는 사람들

{% if followees %} : 만약 내가 팔로우하는 사람들이 있다면

{% for user in followees %} : for문을 돌려 객체 각각의 정보를 user에 저장한다.

user의 이름을 출력하고 이건 내가 팔로우한 사람들이니까 "언팔로우" 버튼을 출력한다.

{% include "header.html" %}

{% block body %}
<div class = "all" style = "width :600px; margin:0 auto;">

    <p>사용자 찾기</p>
    <input type = "text" id = "searchUserName" placeholder = "Enter username..">
    <button id = "search" class = "btn-outline-success">검색</button>
    <p><b id = "searchResult"></b>
    <span id = "searchFollow" style = "display:none;">-<button></button></span></p>
    <hr><hr>

    <h4>날 팔로우하는 사람들</h4>
    {% if followers %}
    <ul class = "list-group">
        {% for myfollower in followers %}
        <li class = "list-group-item col-md-6">
            {{myfollower.follower.username}}
                <!--나를 팔로우하는 사람을 내가 팔로우하지 않은 경우-->
            {% if myfollower.follower.id in followees_ids %}
            - <button class = "unfollow btn btn-outline-success" data-user-id = "{{myfollower.follower.id}}">언팔로우</button>

            {% else %}
            - <button class = "follow btn btn-outline-success" data-user-id = "{{myfollower.follower.id}}">팔로우</button>
            {% endif %}
        </li>
        {% endfor %}
    </ul>
    {% endif %}

    <h4>내가 팔로우하는 사람들</h4>
    {% if followees %}
    <ul class = "list-group">
        {% for user in followees %}
        <li class = "list-group-item col-md-6">{{user.username}} - <button class = "unfollow btn btn-outline-success" data-user-id = "{{user.id}}">언팔로우</button></li>
        {% endfor %}
    </ul>
    {% endif %}
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>

 

 

 

1. 사용자 검색창

"검색" 버튼을 누르면

(1) 찾으려는 사용자 이름에 대한 값을 username에 저장한다.

(2) RelationView에서 전달받은 context['followees_ids'] 값을 가져와서 내가 팔로우하는 사람들에 대한 정보를 저장한다.

(3) UserInfoGet API에 username을 전달하면, API에서는 username, email, id 값을 반환하는데 이 정보들을 obj에 저장한다. 

(4) #searchResult 부분에 obj.data.username 을 표시하여 찾은 결과를 나타낸다.

(5) 검색한 사람이 팔로우한 사람이면 "언팔로우" 버튼, 팔로우 안한 사람이면 "팔로우"버튼 출력한다.

 

- 사용자를 검색했을 때의 결과 화면을 보면서 console.log 로 값을 확인한다.

"one" 사용자가 팔로우 하지 않은 "iamhungry" 사용자를 검색하면 

console.log(username) => 입력한 사용자 이름 "iamhungry"

console.log(obj.data.id)  => "iamhungry" 의 id 번호

console.log(followeesIds) => "one" 이 팔로우하는 사람들의 아이디 목록

console.log(followeesIds.indexOf(obj.data.id)) => "one" 이 팔로우하는 사람들 목록에 "iamhungry"의 id 가 몇 번째에 있는지, 없으면 -1 반환

 

그러면 아래와 같은 결과 화면을 볼 수 있다. 콘솔창에 출력된 대로 one이 iamhungry를 팔로우하지 않아서 -1을 반환했고, -1이 나왔기 때문에 "팔로우"버튼이 출력됐다.

 

 

 

 

 

 

2. "팔로우" 버튼 누르면

팔로우 API로 userId를 전달하여 팔로우 관계를 생성하고 새로고침한다.

 

3. "언팔로우" 버튼 누르면

언팔로우 API로 userId를 전달하여 followee 목록에서 상대방을 제거한 후 새로고침한다.

 

<script>
    $(document).ready(function(){
        $('#search').click(function(){
            var username = $('#searchUserName').val();
            var followeesIds = "{{followees_ids}}";
            $.get("{% url 'apis_user_infoget' %}", {'username' :username}, function(obj){
                $('#searchResult').html(obj.data.username);
                var $searchRelationButton = $('#searchFollow button');
                $searchRelationButton.data('user-id', obj.data.id);

                console.log(username)
                console.log(obj.data.id)
                console.log(followeesIds)
                console.log(followeesIds.indexOf(obj.data.id))

                if (followeesIds.indexOf(obj.data.id) > -1){
                    $searchRelationButton.removeClass('follow');
                    $searchRelationButton.addClass('unfollow');
                    $searchRelationButton.html('언팔로우');
                } else {
                    $searchRelationButton.removeClass('unfollow');
                    $searchRelationButton.addClass('follow');
                    $searchRelationButton.html('팔로우');
                }
                $('#searchFollow').show();
            }).fail(function(data){
                $('#searchResult').html(data.responseJSON.message);
            });
        });

        $('body').delegate('.follow', 'click', function(e){
            var userId = $(e.currentTarget).data('user-id');
            $.post("{% url 'apis_relation_create' %}", {id :userId}, function(){
                location.reload();
            }).fail(function(data){
                alert(data.responseJSON.message);
            });
        });

        $('body').delegate('.unfollow', 'click', function(e){
            var userId = $(e.currentTarget).data('user-id');
            $.post("{% url 'apis_relation_delete' %}", {id : userId}, function(){
                location.reload();
            }).fail(function(data){
                alert(data.responseJSON.message);
            });
        });
    });

</script>
{% endblock %}

 

 

실행 결과

 

 

댓글