Python - Django를 이용한 인스타그램 클론 - 10(강의 최종)

2022. 11. 12. 18:41카테고리 없음

이제 피드를 거의 구현한 것 같으니, 프로필에 들어갔을 때를 구현해줘야 한다. 프로필 창에 우리가 구현한 내가 올린 피드, 좋아요 누른 피드, 북마크한 피드를 표현하기 위해서 간단하게 profile.html에 수정을 가했다.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {% load static %} <!--불러오기-->
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">

    <!--Google Icon-->
    <link
            href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp"
            rel="stylesheet">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />

    <!-- Jquery -->
    <script src="http://code.jquery.com/jquery-latest.min.js">

        <link href="css/bootstrap.css" rel="stylesheet">


    </script>
    <style>
        .box {
            width: 50px;
            height: 50px;
            border-radius: 70%;
            overflow: hidden;
        }

        .profile {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .feed_box {
            margin: 20px 0;
            border: solid 1px gray;
            background-color: white;
        }

        .modal_overlay {
            width: 100%;
            height: 100%;
            position: absolute;
            left: 0;
            top: 0;
            display: none;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(1.5px);
            -webkit-backdrop-filter: blur(1.5px);
        }

        .modal_window {
            background: white;
            backdrop-filter: blur(13.5px);
            -webkit-backdrop-filter: blur(13.5px);
            border-radius: 10px;
            border: 1px solid rgba(255, 255, 255, 0.18);
            width: 800px;
            height: 600px;
            position: relative;
            padding: 10px;
        }

    </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" style="position: fixed; width:100%;">
    <!--flex의 space-between 활용해서, 또 밑으로 새지 않게 nowrap, 반응형이 아니어도 되기에 최소 화면크기를 1000픽셀 -->
    <div class="container-fluid" style="justify-content: space-between; flex-wrap: nowrap; min-width: 1000px"/>
    <a class="navbar-brand" href="/main"> <img style="height: 30px; object-fit: contain"
         src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png">
    </a>
        <input class="form-control" style="width: 200px" type="search" placeholder="Search" aria-label="Search">
    <div style="display:flex;">
        <a style="color: black;" href="/main"><span class="material-icons" style="padding-right: 10px">home</span></a>
        <span id="nav_bar_add_box" class="material-icons-outlined" style="cursor:pointer; padding-right: 10px">add_box</span>
        <div class="dropdown">
            <a id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <div class="box" style="width: 25px; height: 25px">
                    <img class="profile"
                         src="{% get_media_prefix %}{{ user.profile_image }}">
                </div>
            </a>
            <div class="dropdown-menu" style="left: -158px" aria-labelledby="dropdownMenuButton">
                <a class="dropdown-item" href="#">프로필</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="/user/logout">로그아웃</a>
            </div>
        </div>
    </div>
</nav>


<div style="display: flex; flex-direction: row; justify-content: center; padding-top: 60px; background-color: #fafafa">
    <div style="padding: 20px 60px">
        <div class="box" style="width: 175px; height: 175px;">
            <img class="profile"
                 src="{% get_media_prefix %}{{ user.profile_image }}">
        </div>
    </div>
    <div style="text-align: left;">
        <div style="display: flex; flex-display:row; margin: 20px 0px;">
            <div style="font-size: 26px; margin-right: 40px">
                {{ user.nickname }}
            </div>
            <button id="button_profile_upload" style="margin-right: 40px">프로필 사진 편집</button>
            <input type="file" id="input_fileupload" style="display: none;" onchange="profile_upload();">
            <span style="margin-right:40px;" class="material-symbols-outlined">settings</span>
        </div>
        <div style="margin-bottom: 20px">
            게시물 내 게시물 건수 팔로워 111 팔로잉 111
        </div>
        <div>
            <b>{{ user.name }}</b>
        </div>
    </div>
</div>

<div style="border-top: solid rgba(50, 50, 50, 0.1) 2px; width: 100%;">

    <div style="display: flex; flex-direction: row; justify-content: center;  margin:20px; ">
        <div style="margin: 0 30px; display: flex; flex-display:row;">
            <span class="material-symbols-outlined">grid_on</span>
            내 게시물
        </div>
        <div style="margin: 0 30px; display: flex; flex-display:row;">
            <span class="material-symbols-outlined">favorite_border</span>
            좋아요
        </div>
        <div style="margin: 0 30px; display: flex; flex-display:row;">
            <span class="material-symbols-outlined">bookmark_border</span>
            북마크
        </div>
    </div>

</div>

<!-- 첫 번째 모달 : 이미지 업로드 용 -->
<div id="first_modal" class="modal_overlay">
    <div class="modal_window">
        <div style="display: flex; flex-direction: row; justify-content: space-between">
            <div style="width: 40px">
            </div>
            <div>
                새 이미지 업로드
            </div>
            <div>
                <span style="cursor:pointer;" class="modal_close material-icons">close</span>
            </div>
        </div>
        <div class="img_upload_space" style="border-top: solid 1px gray; margin-top: 10px; width:778px; height: 540px;">
        </div>
    </div>
</div>

<!-- 두 번째 모달 : 내용 탑재용 -->
<div id="second_modal" class="modal_overlay">
    <div class="modal_window">
        <div style="display: flex; flex-direction: row; justify-content: space-between">
            <div style="width: 40px">
            </div>
            <div>
                새 이미지 업로드
            </div>
            <div>
                <span style="cursor:pointer;" class="modal_close material-icons">close</span>
            </div>
        </div>
        <div style="border-top: solid 1px gray; margin-top:10px; display: flex; flex-direction: row;">

            <div class="img_upload_space" style="width:500px; height: 540px;">
            </div>
            <div style="border-left: 1px solid gray">
                <div>
                    <textarea id="input_feed_content" style="width: 276px; height: 400px" class="form-control"
                              rows="5"></textarea>
                </div>
                <button id="feed_create_button" type="button" class="btn btn-primary" style="width:100%">공유하기</button>
            </div>
        </div>
    </div>
</div>


<!-- Jquery -->
<script>

     $('.modal_close').click(function () {
        $('#first_modal').css({
            display: 'none'
        });
        $('#second_modal').css({
            display: 'none'
        });
    });

    let files;

    $('#feed_create_button').click(function () {

        let file = files[0];
        let image = files[0].image;
        let content = $('#input_feed_content').val();
// 우선 user_id와 profile_image는 우리가 html에 데이터로 불러온게 아닌 그냥 삽입해둔 상태라 다른 방식을 거치지 않고 그대로 작성해주었다.

        let fd = new FormData();

        fd.append('file', file);
        fd.append('image', image);
        fd.append('content', content);
        // form data에 데이터 추가

        $.ajax({
            url: "/content/upload",
            data: fd,
            method: "post",
            processData: false,
            contentType: false,
            success: function (data) {
                console.log("성공");
            },
            error: function (request, status, error) {
                console.log("에러");
            },
            complete: function () {
                console.log("완료");
                location.replace("/main");
            }
        })
    });

    $('#nav_bar_add_box').click(function () {
        $('#first_modal').css({
            display: 'flex'
        });

        $(document.body).css({
            overflowY: 'hidden'
        })

    });

    $('.img_upload_space')
        .on("dragover", dragOver)
        .on("dragleave", dragOver)
        .on("drop", uploadFiles);

    function dragOver(e) {
        e.stopPropagation(); // img_upload_space와 겹쳐진 부분에 탑재되는 것을 막는 역할
        e.preventDefault();

        if (e.type == "dragover") {
            $(e.target).css({
                "background-color": "black",
                "outline-offset": "-20px"
            });
        } else { // dragleave 인 경우
            $(e.target).css({
                "outline-offset": "-10px"
            });
        }
    }

    function uploadFiles(e) {
        e.stopPropagation();
        e.preventDefault();

        e.dataTransfer = e.originalEvent.dataTransfer; // 올린 파일을 업로드 하는
        files = e.target.files || e.dataTransfer.files;
        console.log("뭔가 이미 파일을 올렸네 " + files[0].name); // 파일을 드래그 해서 여러개 올릴 수도 있기에 files내 리스트처럼 접근해야한다
        if (files.length > 1) {
            alert('하나만 올려라.');
            return;
        }


        if (files[0].type.match(/image.*/)) {


            $('#first_modal').css({
                display: 'none'
            });
            $('#second_modal').css({
                display: 'flex'
            });

            $('.img_upload_space').css({
                "background-image": "url(" + window.URL.createObjectURL(files[0]) + ")",
                "outline": "none",
                "background-size": "100%",
                "background-position": "center",
                "background-repeat": "no-repeat"
            }); // 이미지 파일인 경우 그걸로 배경설정
        } else {
            alert('이미지가 아닙니다.');
            return;
        }
    }

    $('#button_profile_upload').click(function (){
       $('#input_fileupload').click();
    });

    function profile_upload(){
        let file = $('#input_fileupload')[0].files[0]
        let email = "{{ user.email }}";

        let fd = new FormData()

        fd.append('file', file);
        fd.append('email', email);

        $.ajax({
            url: "/user/profile/upload",
            data: fd,
            method: "POST",
            processData: false,
            contentType: false,
            success: function (data) {
                console.log("성공");
            },
            error: function (request, status, error) {
                console.log("에러");
            },
            complete: function () {
                console.log("완료");
                location.replace("/content/profile");
            }
        })
    }

</script>


<!-- Bootstrap Bundle-->
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
        crossorigin="anonymous"></script>


</body>


</html>

그리고 views에서 profile 부분에서 해당 피드들을 불러오기 위한 설정들을 넣었다.

class Profile(APIView):
    def get(self, request):
        email = request.session.get('email', None)

        if email is None:
            return render(request, "user/login.html")

        user = User.objects.filter(email=email).first()  # 웹 서버 세션에 등록된 이메일 정보를 통해 유저 데이터 불러온다

        if user is None:
            return render(request, "user/login.html")

        feed_list = Feed.objects.filter(email=email).all()
        like_list = list(Like.objects.filter(email=email, is_like=True).all().values_list('feed_id', flat=True))
        # values_list 하면 속성명을 지정해서 해당 데이터만 가져올 수 있다 - query set으로 반환되는데 이를 list로 받아오기 위해서 list로 감싸주기
        like_feed_list = Feed.objects.filter(id__in=like_list)
        # id__in? 피드에 있는 아이디 중에 like_list 내에 있는 피드만 선택해서 가져올 수 있다
        bookmark_list = list(Bookmark.objects.filter(email=email, is_marked=True).all().value_list('feed_id', flat=True))
        bookmark_feed_list = Feed.objects.filter(id__in=bookmark_list)


        return render(request, 'content/profile.html', context=dict(feed_list=feed_list,
                                                                    like_feed_list=like_feed_list,
                                                                    bookmark_feed_list=bookmark_feed_list,
                                                                    user=user))

like_feed_list와 bookmark_feed_list로 내가 좋아요 누른 피드와 북마크 누른 피드를 불러올 수 있도록 하고 이를 넘겨줬다.

 

이제 profile.html을 수정해서 내가 누른부분에 따라 피드가 표현되게 해줘야한다.

(근데 그 전에 views.py의 UploadFeed클래스에 Feed.objects.create 부분에 like_account를 넘겨주는 걸 없애주자, 글 올릴때 오류 뜨더라,,)

그리고 main.html에 for문으로 가져온 정보들을 돌아가면서 출력하게 해주었다.(내가 올린 피드부분)

<div style="width:100%; min-width:1000px; display:flex; justify-content: center; align-items: center;">
<div style="display:flex; flex-direction: row; flex-wrap: wrap; width: 1000px; justify-content: center;">
    {% for feed in feed_list %}
        <div style="width:300px; height:300px; margin: 10px 5px 0px 5px;">
            <div>
                <img style="width:300px; height:300px; object-fit: cover" src="{% get_media_prefix %}{{ feed.image }}">
            </div>
        </div>
    {% endfor %}
</div>
</div>

여러 CSS를 추가한 전체 main.html 파일은 아래와 같다

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {% load static %} <!--불러오기-->
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.1/dist/css/bootstrap.min.css" rel="stylesheet"
          integrity="sha384-iYQeCzEYFbKjA/T2uDLTpkwGzCiq6soy8tYaI1GyVh/UjpbCx/TYkiZhlZB6+fzT" crossorigin="anonymous">

    <!--Google Icon-->
    <link
            href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined|Material+Icons+Two+Tone|Material+Icons+Round|Material+Icons+Sharp"
            rel="stylesheet">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />

    <!-- Jquery -->
    <script src="http://code.jquery.com/jquery-latest.min.js">

        <link href="css/bootstrap.css" rel="stylesheet">


    </script>
    <style>
        .box {
            width: 50px;
            height: 50px;
            border-radius: 70%;
            overflow: hidden;
        }

        .profile {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .feed_box {
            margin: 20px 0;
            border: solid 1px gray;
            background-color: white;
        }

        .modal_overlay {
            width: 100%;
            height: 100%;
            position: absolute;
            left: 0;
            top: 0;
            display: none;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(1.5px);
            -webkit-backdrop-filter: blur(1.5px);
        }

        .modal_window {
            background: white;
            backdrop-filter: blur(13.5px);
            -webkit-backdrop-filter: blur(13.5px);
            border-radius: 10px;
            border: 1px solid rgba(255, 255, 255, 0.18);
            width: 800px;
            height: 600px;
            position: relative;
            padding: 10px;
        }

    </style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light" style="position: fixed; width:100%;">
    <!--flex의 space-between 활용해서, 또 밑으로 새지 않게 nowrap, 반응형이 아니어도 되기에 최소 화면크기를 1000픽셀 -->
    <div class="container-fluid" style="justify-content: space-between; flex-wrap: nowrap; min-width: 1000px"/>
    <a class="navbar-brand" href="/main"> <img style="height: 30px; object-fit: contain"
         src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png">
    </a>
        <input class="form-control" style="width: 200px" type="search" placeholder="Search" aria-label="Search">
    <div style="display:flex;">
        <a style="color: black;" href="/main"><span class="material-icons" style="padding-right: 10px">home</span></a>
        <span id="nav_bar_add_box" class="material-icons-outlined" style="cursor:pointer; padding-right: 10px">add_box</span>
        <div class="dropdown">
            <a id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <div class="box" style="width: 25px; height: 25px">
                    <img class="profile"
                         src="{% get_media_prefix %}{{ user.profile_image }}">
                </div>
            </a>
            <div class="dropdown-menu" style="left: -158px" aria-labelledby="dropdownMenuButton">
                <a class="dropdown-item" href="#">프로필</a>
                <div class="dropdown-divider"></div>
                <a class="dropdown-item" href="/user/logout">로그아웃</a>
            </div>
        </div>
    </div>
</nav>


<div style="display: flex; flex-direction: row; justify-content: center; padding-top: 60px; background-color: #fafafa">
    <div style="padding: 20px 60px">
        <div class="box" style="width: 175px; height: 175px;">
            <img class="profile"
                 src="{% get_media_prefix %}{{ user.profile_image }}">
        </div>
    </div>
    <div style="text-align: left;">
        <div style="display: flex; flex-display:row; margin: 20px 0px;">
            <div style="font-size: 26px; margin-right: 40px">
                {{ user.nickname }}
            </div>
            <button id="button_profile_upload" style="margin-right: 40px">프로필 사진 편집</button>
            <input type="file" id="input_fileupload" style="display: none;" onchange="profile_upload();">
            <span style="margin-right:40px;" class="material-symbols-outlined">settings</span>
        </div>
        <div style="margin-bottom: 20px">
            게시물 내 게시물 건수 팔로워 111 팔로잉 111
        </div>
        <div>
            <b>{{ user.name }}</b>
        </div>
    </div>
</div>

<div style="border-top: solid rgba(50, 50, 50, 0.1) 2px; width: 100%;">

    <div style="display: flex; flex-direction: row; justify-content: center;  margin:20px; ">
        <div style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">grid_on</span>내 게시물</div>
        <div style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">favorite_border</span>좋아요</div>
        <div style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">bookmark_border</span>북마크</div>
    </div>

</div>

<div style="width:100%; min-width:1000px; display:flex; justify-content: center; align-items: center;">
<div style="display:flex; flex-direction: row; flex-wrap: wrap; width: 1000px; justify-content: center;">
    {% for feed in feed_list %}
        <div style="width:300px; height:300px; margin: 10px 5px 0px 5px;">
            <div>
                <img style="width:300px; height:300px; object-fit: cover" src="{% get_media_prefix %}{{ feed.image }}">
            </div>
        </div>
    {% endfor %}
</div>
</div>

<!-- 첫 번째 모달 : 이미지 업로드 용 -->
<div id="first_modal" class="modal_overlay">
    <div class="modal_window">
        <div style="display: flex; flex-direction: row; justify-content: space-between">
            <div style="width: 40px">
            </div>
            <div>
                새 이미지 업로드
            </div>
            <div>
                <span style="cursor:pointer;" class="modal_close material-icons">close</span>
            </div>
        </div>
        <div class="img_upload_space" style="border-top: solid 1px gray; margin-top: 10px; width:778px; height: 540px;">
        </div>
    </div>
</div>

<!-- 두 번째 모달 : 내용 탑재용 -->
<div id="second_modal" class="modal_overlay">
    <div class="modal_window">
        <div style="display: flex; flex-direction: row; justify-content: space-between">
            <div style="width: 40px">
            </div>
            <div>
                새 이미지 업로드
            </div>
            <div>
                <span style="cursor:pointer;" class="modal_close material-icons">close</span>
            </div>
        </div>
        <div style="border-top: solid 1px gray; margin-top:10px; display: flex; flex-direction: row;">

            <div class="img_upload_space" style="width:500px; height: 540px;">
            </div>
            <div style="border-left: 1px solid gray">
                <div>
                    <textarea id="input_feed_content" style="width: 276px; height: 400px" class="form-control"
                              rows="5"></textarea>
                </div>
                <button id="feed_create_button" type="button" class="btn btn-primary" style="width:100%">공유하기</button>
            </div>
        </div>
    </div>
</div>


<!-- Jquery -->
<script>

     $('.modal_close').click(function () {
        $('#first_modal').css({
            display: 'none'
        });
        $('#second_modal').css({
            display: 'none'
        });
    });

    let files;

    $('#feed_create_button').click(function () {

        let file = files[0];
        let image = files[0].image;
        let content = $('#input_feed_content').val();
// 우선 user_id와 profile_image는 우리가 html에 데이터로 불러온게 아닌 그냥 삽입해둔 상태라 다른 방식을 거치지 않고 그대로 작성해주었다.

        let fd = new FormData();

        fd.append('file', file);
        fd.append('image', image);
        fd.append('content', content);
        // form data에 데이터 추가

        $.ajax({
            url: "/content/upload",
            data: fd,
            method: "post",
            processData: false,
            contentType: false,
            success: function (data) {
                console.log("성공");
            },
            error: function (request, status, error) {
                console.log("에러");
            },
            complete: function () {
                console.log("완료");
                location.replace("/main");
            }
        })
    });

    $('#nav_bar_add_box').click(function () {
        $('#first_modal').css({
            display: 'flex'
        });

        $(document.body).css({
            overflowY: 'hidden'
        })

    });

    $('.img_upload_space')
        .on("dragover", dragOver)
        .on("dragleave", dragOver)
        .on("drop", uploadFiles);

    function dragOver(e) {
        e.stopPropagation(); // img_upload_space와 겹쳐진 부분에 탑재되는 것을 막는 역할
        e.preventDefault();

        if (e.type == "dragover") {
            $(e.target).css({
                "background-color": "black",
                "outline-offset": "-20px"
            });
        } else { // dragleave 인 경우
            $(e.target).css({
                "outline-offset": "-10px"
            });
        }
    }

    function uploadFiles(e) {
        e.stopPropagation();
        e.preventDefault();

        e.dataTransfer = e.originalEvent.dataTransfer; // 올린 파일을 업로드 하는
        files = e.target.files || e.dataTransfer.files;
        console.log("뭔가 이미 파일을 올렸네 " + files[0].name); // 파일을 드래그 해서 여러개 올릴 수도 있기에 files내 리스트처럼 접근해야한다
        if (files.length > 1) {
            alert('하나만 올려라.');
            return;
        }


        if (files[0].type.match(/image.*/)) {


            $('#first_modal').css({
                display: 'none'
            });
            $('#second_modal').css({
                display: 'flex'
            });

            $('.img_upload_space').css({
                "background-image": "url(" + window.URL.createObjectURL(files[0]) + ")",
                "outline": "none",
                "background-size": "100%",
                "background-position": "center",
                "background-repeat": "no-repeat"
            }); // 이미지 파일인 경우 그걸로 배경설정
        } else {
            alert('이미지가 아닙니다.');
            return;
        }
    }

    $('#button_profile_upload').click(function (){
       $('#input_fileupload').click();
    });

    function profile_upload(){
        let file = $('#input_fileupload')[0].files[0]
        let email = "{{ user.email }}";

        let fd = new FormData()

        fd.append('file', file);
        fd.append('email', email);

        $.ajax({
            url: "/user/profile/upload",
            data: fd,
            method: "POST",
            processData: false,
            contentType: false,
            success: function (data) {
                console.log("성공");
            },
            error: function (request, status, error) {
                console.log("에러");
            },
            complete: function () {
                console.log("완료");
                location.replace("/content/profile");
            }
        })
    }

</script>


<!-- Bootstrap Bundle-->
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
        crossorigin="anonymous"></script>


</body>


</html>

실행해보면

잘 실행되는지를 보기위해 몇 가지 글을 더 섰다

잘 나타난다.

이게 좋아요, 북마크 별로도 보여져야하는데 작성한 코드의 조금만 수정해주면된다.

<div style="display: flex; flex-direction: row; justify-content: center;  margin:20px; ">
        <div id="button_feed_list" style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">grid_on</span>내 게시물</div>
        <div id="button_feed_like_list"style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">favorite_border</span>좋아요</div>
        <div id="button_feed_bookmark_list"style="margin: 0 30px; display: flex; flex-display:row;"><span class="material-symbols-outlined">bookmark_border</span>북마크</div>
    </div>

우선 material icon별로 클릭하면 보여지게 해야하므로 id값을 위처럼 각각 부여한다,

그리고 나서

<div id="feed_list" style="width:100%; min-width:1000px; display:flex; justify-content: center; align-items: center;">
<div style="display:flex; flex-direction: row; flex-wrap: wrap; width: 1000px; justify-content: center;">
    {% for feed in feed_list %}
        <div style="width:300px; height:300px; margin: 10px 5px 0px 5px;">
            <div>
                <img style="width:300px; height:300px; object-fit: cover" src="{% get_media_prefix %}{{ feed.image }}">
            </div>
        </div>
    {% endfor %}
</div>
</div>

<div id="like_feed_list" style="width:100%; min-width:1000px; display:none; justify-content: center; align-items: center;">
<div style="display:flex; flex-direction: row; flex-wrap: wrap; width: 1000px; justify-content: center;">
    {% for feed in like_feed_list %}
        <div style="width:300px; height:300px; margin: 10px 5px 0px 5px;">
            <div>
                <img style="width:300px; height:300px; object-fit: cover" src="{% get_media_prefix %}{{ feed.image }}">
            </div>
        </div>
    {% endfor %}
</div>
</div>

<div id="bookmark_feed_list" style="width:100%; min-width:1000px; display:none; justify-content: center; align-items: center;">
<div style="display:flex; flex-direction: row; flex-wrap: wrap; width: 1000px; justify-content: center;">
    {% for feed in bookmark_feed_list %}
        <div style="width:300px; height:300px; margin: 10px 5px 0px 5px;">
            <div>
                <img style="width:300px; height:300px; object-fit: cover" src="{% get_media_prefix %}{{ feed.image }}">
            </div>
        </div>
    {% endfor %}
</div>
</div>

이렇게 feed_list와 거의 유사하게 나머지 like_feed_list와 bookmark_feed_list를 작성해주면 되고 우선 처음 들어갔을 땐 feed_list가 먼저 보여야하므로 display를 feed_list 빼고는 다 None으로 설정해준다.

이후 제이쿼리를 작성해서 버튼이 눌리면, 각 부분이 display:flex로 바뀌도록 해주면 되겠다

// button_feed_list 눌렸을 때
    $('#button_feed_list').click(function(){
        $('#feed_list').css({
            display: 'flex'
        });
            $('#like_feed_list').css({
                display: 'none'
            });
        $('#bookmark_feed_list').css({
            display: 'none'
        });
    });

    // button_feed_like_list 눌렸을 때
    $('#button_feed_like_list').click(function(){
        $('#feed_list').css({
            display: 'none'
        });
            $('#like_feed_list').css({
                display: 'flex'
            });
        $('#bookmark_feed_list').css({
            display: 'none'
        });
    });

    // button_bookmark_feed
    $('#button_feed_bookmark_list').click(function(){
        $('#feed_list').css({
            display: 'none'
        });
            $('#like_feed_list').css({
                display: 'none'
            });
        $('#bookmark_feed_list').css({
            display: 'flex'
        });
    });

실행해보면,

잘 작동된다. 

아직 몇가지 수행하지 못한 기능들이 존재하는데, 우선은 여기까지 최종으로 마치고, 점차 시간날 때 마다 진짜 사용할만한 서비스 같이 보완해나가도록 하겠다. 팔로워 팔로잉, 추천친구 등등,, 할게 많네

봐주셔서 감사합니다