ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Django 클론코딩으로 인스타그램을 ! 1탄
    공부 !/Django·Web 2022. 3. 24. 16:16
    반응형

    Clone Coding

    클론코딩 .. 정의부터 알아보자

    클론코딩이란 인스타그램, 유튜브 등 실제 서비스를 따라 만들어보는 공부방식이다

    상용화된 서비스를 직접 구현해보며 기획적인 요소나 개발적 요소를 이해하는데 도움이 될 것 같아 시작한다 !

     

    이 포스팅에서는 장고로 인스타그램을 클론코딩한다


    프로젝트 생성하기

    프로젝트를 시작하기 앞서 가상환경을 만들고 새 프로젝트를 생성한다

    가상환경은 instavenv 프로젝트명은 instaprj 앱명은 instapp 으로 정했다

    여러 기능을 가진 앱들이 하나의 프로젝트 내에 존재할 때 프로젝트의 urls.py 가 복잡해진다

    url 를 app 별로 관리해주면 이를 해결할 수 있다 !

    장고 url 이 제공하는 include() 함수를 사용하면 편리하게 기능별로 urls.py 를 관리할 수 있다

     

    뭔 .. 하는 생각이 든다면 아래 URL 을 방문해보면 도움이 될 것 같다 ( 광고 아님 )

    https://kangsu-2ji.tistory.com/10

     

    Django 개념 및 로컬 서버 돌리기 !

    DJANGO Django 는 쿠엔틴 타란티노 감독의 영화이다 ... 아니 정말로 Django 란 무엇일까 ? 파이썬으로 만들어진 웹 애플리케이션 프레임워크(web application framework) 이다. 쉽게 말해 빠르게 웹사이트를

    kangsu-2ji.tistory.com

     

    웹 페이지까지 실행시켰다면 준비 완료 ! 


     

    Urls.py 와 Views.py 

    instapp/templates 에 main.html 를 생성한 후 아래와 같이 작성해주자

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Sootagram</title>
      </head>
    	<body>
        이 화면을 수정해서 인스타를 만들 예정 !
      </body>
    </html>

    html 내 작성된 내용을 우리 장고 웹서버에 띄우기 위해서는 urls.py 와 views.py 를 수정해야한다

    그렇다면 urls.py 와 views.py 란 무엇일지부터 알아보자

     

    urls.py 란 URL 이 요청되면 뷰 함수를 호출하라는 urlpattern을 관리하고 요청시 해당 뷰 함수와 매핑시킨다

    views.py 란 데이터를 처리하는 로직인 뷰 함수를 정의한다

    아래 그림을 통해 장고의 기본적인 흐름을 정리해두면 좋다

     

    요청시 URL 매핑을 확인하여 views 내 함수를 호출하여 결과를 브라우저에 반영 !

    흐름을 기억하면서 !  instapp/views.py 를 작성해보자

    from django.shortcuts import render
    from rest_framework.views import APIView
    
    class Main(APIView): 
        def get(self, request):
            return render(request, 'main.html')

    파이썬은 만들어진 코드를 패키지 형태로 다운로드하여 사용할 수 있다

    APIView 라는 기능을 사용하기 위해서 추가로 djangorestframework 라는 패키지를 설치해야한다

    아래 코드를 쳐서 설치하자 !

    $ pip install djangorestframework

    우리가 작성한 Main 클래스는 APIView 기능을 사용한다 

    여기서 APIView 는 클라이언트와 서버가 데이터를 주고 받을 수 있도록 돕는 역할이다

    Main 클래스 내에 정의한 def get(self, request): 는 get 으로  Main 클래스를 실행할 경우

    render 기능을 사용하여 우리가 작성한 'main.html'를 브라우저에 보여준다 !

     

    views.py 내용을 이해했으면 urls.py 를 작성하자

    instapp/urls.py 를 작성하고 instaprj/urls.py include 해주면 된다

    intstapp/urls.py

    from django.urls import path
    from .views import Main
    
    urlpatterns = [
        path('', Main.as_view())
    ]

    instapfj/urls.py

    """instaprj URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/3.2/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include('instapp.urls')),
    ]

     

    위 코드를 작성한 후 서버를 실행시키면 아래 화면과 같이 결과가 나오게 된다 !


    페이지 꾸미기

    페이지를 꾸미기 앞서 인스타그램의 메뉴바를 캡처해왔다

    우리는 부트스트랩과 구글 폰트의 아이콘을 사용하여 인스타그램 메뉴바를 만들 예정이다 

    insta nav bar

    부트스트랩이란 웹 페이지 템플릿 모음으로  부트스트랩/시작하기에 있는 스타터 템플릿을

    장고의 html 복사하면 사용할 수 잇다 우리가 적었던 내용을 지우고 붙여 넣어보자 !

    <!doctype html>
    <html lang="en">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    
        <title>Hello, world!</title>
      </head>
      <body>
        <h1>Hello, world!</h1>
    
        <!-- Optional JavaScript; choose one of the two! -->
    
        <!-- Option 1: Bootstrap Bundle with Popper -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
    
        <!-- Option 2: Separate Popper and Bootstrap JS -->
        <!--
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
        -->
      </body>
    </html>

    붙여넣고 실행해도 달라지는건 크게 없다 여기에 navbar 를 붙여 비슷한 구조를 만들자

    body 태그 내에 아래 코드를 붙여넣어주는데 아래 코드는 컴포넌트/ 네비게이션바에서 지원하는 콘텐츠이다

    그림과 같은 네비게이션 바를 만들어주는 아래 코드 !

    <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <div class="container-fluid">
        <a class="navbar-brand" href="#">Navbar</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse"
                data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarSupportedContent">
          <ul class="navbar-nav me-auto mb-2 mb-lg-0">
            <li class="nav-item">
              <a class="nav-link active" aria-current="page" href="#">Home</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="#">Link</a>
            </li>
            <li class="nav-item dropdown">
              <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
                 data-bs-toggle="dropdown" aria-expanded="false">
                Dropdown
              </a>
              <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
                <li><a class="dropdown-item" href="#">Action</a></li>
                <li><a class="dropdown-item" href="#">Another action</a></li>
                <li>
                  <hr class="dropdown-divider">
                </li>
                <li><a class="dropdown-item" href="#">Something else here</a></li>
              </ul>
            </li>
            <li class="nav-item">
              <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
            </li>
          </ul>
          <form class="d-flex">
            <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
            <button class="btn btn-outline-success" type="submit">Search</button>
          </form>
        </div>
      </div>
    </nav>

     

    약간 이제 비슷해질랑 말랑 !

    인스타그램 마크로 Navbar 제목을 바꿔주자 !

    F12 개발자 모드로 인스타그램의 이미지 주소를 복사하여 우리의 네비바에 넣어준다 !

               <img style="height: 30px; object-fit: contain" src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png">
                <input class="form-control" style="width: 200px" type="search" placeholder="Search" aria-label="Search">

    아주 그럴싸해지기 시작 ~


    벌써 들뜨면 안되지만 그럴싸해지기 시작한다 자 오른쪽 버튼들을 구현해보자 

    버튼의 아이콘은 구글 font의 icon 을 통해 구현하면 된다

    Icons - Google Fonts

     

    Google Fonts

    Making the web more beautiful, fast, and open through great typography

    fonts.google.com

     

    아이콘을 사용하기 앞서 부트스트랩처럼 head 태그 내에 url 를 적어준다

        <!-- 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">

    사용하고 싶은 아이콘들을 검색하여 span 으로 시작하는 소스코드를 우리의 html 에 넣어주면 된다

    아래는 아이콘을 포함한 전체 코드이다

    <!doctype html>
    <html lang="en">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" 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">
    
        <title>Sootagram</title>
      </head>
      <body>
        
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <div class="container">
                <img style="height: 30px; object-fit: contain" src="https://www.instagram.com/static/images/web/mobile_nav_type_logo-2x.png/1b47f9d0e595.png">
                <input class="form-control" style="width: 200px" type="search" placeholder="Search" aria-label="Search">
    
                <!-- navbar icons -->
                <div>
                    <span class="material-icons">home</span>
                    <span class="material-icons">send</span>
                    <span class="material-icons-outlined">add_box</span>
                    <span class="material-icons-outlined">explore</span>
                    <span class="material-icons-outlined">favorite_border</span>
                </div>
            </div>
        </nav>
    
        <!-- Optional JavaScript; choose one of the two! -->
    
        <!-- Option 1: Bootstrap Bundle with Popper -->
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
    
        <!-- Option 2: Separate Popper and Bootstrap JS -->
        <!--
        <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
        -->
      </body>
    </html>

    따란 ! 보기에 이제 그럴싸해졌다 :D

    다음 포스팅에서는 인스타그램 피드를 구현해보자 !

    아이콘과 네비바를 어느정도 따라한 insta !


    참고

    https://wikidocs.net/70649#viewspy

     

    2-01 URL과 뷰

    `[완성 소스]` : [github.com/pahkey/djangobook/tree/2-01](https://github.com/pahkey/djangobook/tree/2 ...

    wikidocs.net

    반응형

    댓글

Designed by SooJI