티스토리 뷰

<Complete List>

1. 데이터베이스 및 UI 설계하기

  • 인스타그램 UI 구성
  • 데이터베이스 테이블 설계 및 구현

2. 앱 만들기

  • instagram, accounts 앱 만들기
  • views.py 분리하기

3. 회원가입 페이지

  • 비밀번호 암호화 함수 구현 - 해시 함수

4. 로그인 페이지

  • 세션에 사용자 ID 저장하기

5. 로그아웃 뷰

6. 메인 페이지

7. 포스트 리스트 페이지

8. 포스트 상세 페이지

9. 포스트 업로드 페이지

10. 회원 정보 수정 페이지

 

<To Do List>

11. 비밀번호 수정 페이지

7-1. 포스트 리스트 페이지

  • 팔로우 뷰 / 언팔로우 뷰

 


11. 비밀번호 수정 페이지

  • accounts에서 작업

11.1 url

urlpatterns = [
    re_path(r'^register/$', RegisterAccountsView, name='pn_reg_accounts'),
    re_path(r'^login/$', LoginView, name='pn_login'),
    re_path(r'^logout/$', LogoutView, name='pn_logout'),
    re_path(r'^modify/$', AccountsModifyView, name='pn_accounts_modify'),
    re_path(r'^password_modify/$', PasswordModifyView, name='pn_password_modify'),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

11.2 PasswordModifyView

  • splitviews 디렉토리에 PasswordModifyView.py 생성

  • splitviews 의 __init.py__에 PasswordModifyView 를 import

 

  • 로직(전체코드 - github)
  1. request.method == GET
    : password_modify.html rendering
  2. request.method == POST
    : password_modify.html의 form 데이터를 받아와 현재 비밀번호로 자격증명 후,
    자격증명에 성공한 user에 대해서만 새로운 비밀번호로 비밀번호 변경
    2.1 password_modify.html의 form 데이터를 받아온다.
    2.2 사용자가 입력한 현재 비밀번호가 맞는 비밀번호인가?: check_password()

    ​ 2.2.1 맞는 비밀번호

    → 에러 메시지와 함께 password_modify.html로 redirect

     2.2.2 틀린 비밀번호

    → 새로운 비밀번호로 변경한 후, login.html로 redirect

 

11.3 password_modify.html

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    $(document).ready(function(){
        //새 비밀번호 - 현재 비밀번호와 같은 경우 에러 메시지 띄우기
        $('#new_user_pw').change(function(){
            exist_user_pw = $('#exist_user_pw').val();
            new_user_pw = $('#new_user_pw').val();

            if(exist_user_pw == new_user_pw) {
                $('#error_msg1').css('display', 'inline');
                $('#error_msg1').show();
                $('#new_user_pw').css('background-color', '#F6CECE');
            } else {
                $('#error_msg1').hide();
                $('#new_user_pw').css('background-color', '');
            }
        });

        //새 비밀번호 확인 - 새 비밀번호와 다른 경우 에러 메시지 띄우기
        $('#check_user_pw').change(function(){
            new_user_pw = $('#new_user_pw').val();
            check_user_pw = $('#check_user_pw').val();

            if(new_user_pw != check_user_pw) {
                $('#error_msg2').css('display', 'inline');
                $('#error_msg2').show();
                $('#check_user_pw').css('background-color', '#F6CECE');
            } else {
                $('#error_msg2').hide();
                $('#check_user_pw').css('background-color', '');
            }
        });

        //<변경하기 버튼> - 빈칸은 없는지, 모든 칸이 올바르게 입력되었는지 확인
        $('#modifyButton').click(function(){
            exist_user_pw = $('#exist_user_pw').val();
            new_user_pw = $('#new_user_pw').val();
            check_user_pw = $('#check_user_pw').val();

            if($('#new_user_pw').css('background-color') != 'rgb(255, 255, 255)' | $('#check_user_pw').css('background-color') != 'rgb(255, 255, 255)') {
                alert("올바르지 않은 입력 값이 있습니다. 다시 입력해주세요.");
                return false;
            }
            if(exist_user_pw == '' | new_user_pw == '' | check_user_pw == ''){
                alert("입력하지 않은 칸이 있습니다. 모두 입력해주세요.");
                return false;
            }
        });
    });
</script>

 

7-1 포스트 리스트 페이지(팔로우 뷰 / 언팔로우 뷰)

  • pystagram에서 작업
  • 포스트 리스트 페이지의 팔로우 버튼

7-1.1 url

urlpatterns = [
    re_path(r'^$', MainView, name='pn_main'),
    re_path(r'^(?P<user_id>[a-zA-Z0-9-_.]*)/$', PostListView, name='pn_post_list'),
    re_path(r'^p/(?P<post_id>[0-9]+)/$', PostDetailView, name='pn_post_detail'),
    re_path(r'^p/upload/$', PostUploadView, name='pn_post_upload'),
    re_path(r'^follow/(?P<following_id>[a-zA-Z0-9-_.]*)/$', FollowView, name='pn_follow'),
    re_path(r'^unfollow/(?P<following_id>[a-zA-Z0-9-_.]*)/$', UnfollowView, name='pn_unfollow'),
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

 

7-1.2 FollowView / UnfollowView

  • splitviews 디렉토리에 FollowView.py / UnfollowView.py 생성
  • splitviews 의 __init.py__에 FollowView / UnfollowView 를 import
  • (200309 수정) 모두 Ajax로 통신

 

  • 팔로우 뷰 로직(전체코드 - github)

(200309 수정)

  1. 현재 사용자와 팔로우 대상 계정의 아이디를 이용해 following 테이블에 INSERT
  2. post_list.html의 팔로우 수 변경을 위한 팔로우 수 SELECT
  3. 팔로우 수 return

 

  • 언팔로우 뷰 로직(전체코드 - github)

(200309 수정)

  1. 현재 사용자와 언팔로우 대상 계정의 아이디를 이용해 following 테이블에서 DELETE
  2. post_list.html의 팔로우 수 변경을 위한 팔로우 수 SELECT
  3. 팔로우 수 return

 

7-1.3 post_list.html (200309 추가)

  • 전체코드 - github

  • javascript 함수 로직

    • follow() 로직

      1. 클릭된 팔로우 버튼이 어떤 유저에 대한 팔로우 버튼인지 알기 위해 클릭된 element와 클릭된 유저 ID를

        인자로 받는다.

      2. Ajax로 통신

      3. 성공적으로 통신했다면 FollowView 로부터 변경된 팔로우 수를 받아온다.

      4. 팔로우 버튼 → 팔로잉 버튼으로 변경하고, 변경된 팔로우 수를 반영

    • unfollow() 로직

      1. 클릭된 팔로우 버튼이 어떤 유저에 대한 팔로우 버튼인지 알기 위해 클릭된 element와 클릭된 유저 ID를

        인자로 받는다.

      2. Ajax로 통신

      3. 성공적으로 통신했다면 UnfollowView 로부터 변경된 팔로우 수를 받아온다.

      4. 팔로잉 버튼 → 팔로우 버튼으로 변경하고, 변경된 팔로우 수를 반영

...
{% if follow == 0 %}
<button type="button" class="btn btn-primary" id="follow_btn" onclick="follow(this, '{{ postListUser.username }}')">팔로우</button>
{% elif follow == 1 %}
<button type="button" class="btn btn-light" id="follow_btn" onclick="unfollow(this, '{{ postListUser.username }}')">팔로잉</button>
{% endif %}
...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
    function follow(elm, n) {
        $.ajax({
            url: "{% url 'pystagram:pn_follow' 1 %}".replace('1', n),
            data: {'csrfmiddlewaretoken': '{{ csrf_token }}'},
            dataType: "json",
            type: "POST",
            success: function(response) {
                $(elm).attr("class", "btn btn-light");
                $(elm).attr("onclick", "unfollow(this, '" + n + "')");
                $(elm).text("팔로잉");
                // 팔로잉 모달의 팔로우 버튼을 누를 때는 팔로워 수가 변경되지 않도록
                if ($(elm).attr("id") == "follow_btn"){
                	$("#followerCount").text(response.followerCount);
                }    
            },
            error: function(xhr,status) {
                alert(xhr + "!!!" + status + "!!!");
                alert("팔로우를 하는 과정에서 에러가 발생했습니다.");
            }
        });
    }

    function unfollow(elm, n) {
        $.ajax({
            url: "{% url 'pystagram:pn_unfollow' 1 %}".replace('1', n),
            data: {'csrfmiddlewaretoken': '{{ csrf_token }}'},
            dataType: "json",
            type: "POST",
            success: function(response) {
                $(elm).attr("class", "btn btn-primary");
                $(elm).attr("onclick", "follow(this, '" + n + "')");
                $(elm).text("팔로우");
                // 팔로잉 모달의 팔로우 버튼을 누를 때는 팔로워 수가 변경되지 않도록
                if ($(elm).attr("id") == "follow_btn"){
                	$("#followerCount").text(response.followerCount);
                }
            },
            error: function(xhr, status) {
                alert(xhr + "!!!" + status + "!!!");
                alert("언팔로우 하는 과정에서 에러가 발생했습니다.");
            }
        });
    }
</script>
댓글