Bookmark project - 2

[ Bookmark project ]

  • Bootstrap 적용
  • github 업로드
  • pythonanywhere.com을 이용한 배포
  1. bootstrap 적용하기

    • base.html에 bootstrap 설치
      • CDN 스크립트로 설치(리소스 절감 효과, 최신버전 자동 유지, CDN을 사용하면 접속 속도 증가)
      • 다운로드 설치(커스터마이징 가능, 도메인을 넘나들지 않아도 됨)
    • base.html에 레이아웃
    • 각 템플릿 파일에 스타일 적용

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      188
      189
      190
      191
      192
      193
      194
      195
      196
      197
      198
      199
      200
      201
      202
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
      213
      214
      215
      216
      217
      218
      219
      220
      221
      222
      223
      <!--// base.html //-->
      <!DOCTYPE html>
      <html lang="en">
      <head>
      <meta charset="UTF-8">
      <title>{% block title %}{% endblock %}</title>
      {% block extra_css %}
      {% endblock %}
      <!--// CSS 적용 //-->
      <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
      </head>
      <body>
      <!--// nav bar 적용 //-->
      <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <a class="navbar-brand" href="#">Bookmark</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarText">
      <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
      <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
      <a class="nav-link" href="#">Features</a>
      </li>
      <li class="nav-item">
      <!--// create 기능 추가 //-->
      <a class="nav-link" href="{% url 'bookmark:create' %}">Add</a>
      </li>
      </ul>
      <span class="navbar-text">
      Navbar text with an inline element
      </span>
      </div>
      </nav>
      <!--//
      bootstrap 적용하기
      1) base.html에 bootstrap 설치하기
      1-1) CDN 스크립트로 설치하기 : 리소스 절감효과, 최신버전을 자동 유지, CDN을 사용하면 접속 속도가 증가
      1-2) 다운로드해서 설치하기 : 커스터마이징 가능, 도메인 넘나들지 않아도 된다.
      2) base.html에 레이아웃 잡기
      3) 각 템플릿에 스타일 적용하기
      //-->
      <div class="container">
      {% block content %}
      {% endblock %}
      </div>

      {% block extra_script %}
      {% endblock %}
      <!--//
      jQuery Slim 버전은 ajax 기능이 빠져있다.
      min 버전 : 용량을 최소화하 버전 -> 띄어쓰기 생략, 엔터 생략 -> 한줄로 다 되어있어, 수정하기가 힘듬
      beautify : min 버전은 소스코드를 알아보기 힘들기 때문에 beautify해서 다시 보기 좋게 만든다.
      모든 static 리소스들은 캐시가 걸린다. -> 수정 사항이 바로 반영되지 않는다.
      1) 웹 서버에서 캐시 타임 조절 : 자주 수정되는 경우 캐시 타임을 확 줄인다. -> 이미 정해진 타임은 조절할 수 없다.
      2) 스태틱 리소스의 파일명을 변경한다. -> 소스코드 수정이 필요할 수 있다.
      3) 스태틱 리소스 뒤에 Query String을 붙인다. -> 아예 캐싱이 안되도록 한다.
      //-->
      <!--// JS 적용 //-->
      <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
      <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
      </body>
      </html>


      <!--// bookmark_list //-->
      {% extends 'base.html' %}

      {% block title %}
      Bookmark List
      {% endblock %}

      {% block content %}
      <!--// grid system 적용(반응형) //-->
      <div class="row">
      <div class="col"></div>
      <div class="col-12 col-xl-8 col-md-4">
      <a href="{% url 'bookmark:create' %}" class="btn btn-success">add Bookmark</a><br>
      {# bookmark 목록 출력하기 #}
      <!--// table 적용 //-->
      <table class="table">
      <thead>
      <tr>
      <!--// table column 항목 //-->
      <th scope="col">NB</th>
      <th scope="col">Site Name</th>
      <th scope="col">Link</th>
      <th scope="col">Update</th>
      <th scope="col">Delete</th>
      </tr>
      </thead>
      <tbody>
      <!--// table 내용 //-->
      {% for object in object_list %}
      <tr>
      <td>{{object.id}}</td>
      <td>
      <a href="{% url 'bookmark:detail' object.id %}">{{object.site_name}}</a>
      </td>
      <td><a href="{{object.url}}" target="_blank">{{object.url}}</a></td>
      <!--// button 적용 //-->
      <td><a href="{% url 'bookmark:update' object.id %}" class="btn btn-light">수정</a></td>
      <td><a href="{% url 'bookmark:delete' object.id %}" class="btn btn-danger">삭제</a></td>
      </tr>
      {% endfor %}
      </tbody>
      </table>
      </div>
      <div class="col"></div>
      </div>
      {% endblock %}


      <!--// bookmark_create //-->
      {% extends 'base.html' %}

      {% block title %}
      Bookmark Create
      {% endblock %}

      {% block content %}
      <!--// grid system 적용(반응형) //-->
      <div class="row">
      <div class="col"></div>
      <div class="col-12 col-xl-8">
      <!--// alert 적용 //-->
      <div class="alert alert-primary" role="alert">
      Please insert bookmark information.
      </div>
      <form action="" method="post">
      {% csrf_token %}
      {{form.as_p}}
      <input type="submit" value="Create">
      </form>
      </div>
      <div class="col"></div>
      </div>
      {% endblock %}


      <!--// bookmark_update //-->
      {% extends 'base.html' %}

      {% block title %}
      Bookmark Update
      {% endblock %}

      {% block content %}
      <!--// grid system 적용(반응형) //-->
      <div class="row">
      <div class="col"></div>
      <div class="col-12 col-xl-8">
      <!--// alert 적용 //-->
      <div class="alert alert-secondary" role="alert">
      Please change bookmark information.
      </div>
      <form action="" method="post">
      {% csrf_token %}
      {{form.as_p}}
      <input type="submit" value="Update">
      </form>
      </div>
      <div class="col"></div>
      </div>
      {% endblock %}


      <!--// bookmark_delete //-->
      {% extends 'base.html' %}

      {% block title %}
      Bookmark Delete
      {% endblock %}

      {% block content %}
      <!--// grid system 적용(반응형) //-->
      <div class="row">
      <div class="col"></div>
      <div class="col-12 col-xl-8">
      <!--// alert 적용 //-->
      <div class="alert alert-danger" role="alert">
      Do you want to delete {{object.url}}?
      </div>
      <form action="" method="post">
      {% csrf_token %}
      <input type="submit" value="Delete Ok">
      </form>
      </div>
      <div class="col"></div>
      </div>
      {% endblock %}


      <!--// bookmark_detail //-->
      {% extends 'base.html' %}

      {% block title %}
      Bookmark Detail
      {% endblock %}

      {% block content %}
      <!--// grid system 적용(반응형) //-->
      <div class="row">
      <div class="col"></div>
      <div class="col-12 col-xl-8">
      <!--// cards 적용 //-->
      <div class="card" style="width: 18rem;">
      <div class="card-body">
      <h5 class="card-title">{{object.site_name}}</h5>
      <h6 class="card-subtitle mb-2 text-muted"><a href="{{object.url}}">{{object.url}}</a></h6>
      <p class="card-text">{{object.contents}}</p>
      <!--// button 적용 //-->
      <a href="{% url 'bookmark:update' object.id %}" class="card-link btn btn-outline-warning">수정</a>
      <a href="{% url 'bookmark:delete' object.id %}" class="card-link btn btn-outline-danger">삭제</a>
      </div>
      </div>
      </div>
      <div class="col"></div>
      </div>
      {% endblock %}
    • models.py에 text를 담기 위해 필드 추가

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      from django.db import models

      class Bookmark(models.Model):
      site_name = models.CharField(max_length=50)
      url = models.URLField()

      # contents 필드 추가
      # 내용을 아무것도 안 적을 수 있기 때문에 blank=True 적용
      contents = models.TextField(blank=True)

      created = models.DateTimeField(auto_now_add=True)


      def __str__(self):
      return "Site name : "+self.site_name+", URL : "+self.url

      class Meta:
      ordering = ['site_name']
    • 관리자 페이지를 커스터마이징하기 위해 admins.py 수정

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      from django.contrib import admin

      # Register your models here.
      # 관리자 페이지에서 관리할 모델을 등록
      # 관리자 페이지를 커스터마이징

      # 옵션 클래스를 만들어서 추가
      from .models import Bookmark

      class BookmarkOptions(admin.ModelAdmin):
      list_display = ['id', 'site_name', 'url']
      # list_editable = ['site_name', 'url']
      # list_filter = ['url'] # 대부분 DateTime 필드가 있을 경우 많이 사용
      search_fields = ['site_name', 'url'] # ForeignKey 필드 값 같이 다른 테이블을 참조하는 항목은 X
      # raw_id_fields : 선택값 -> 입력값
      # 관리자 페이지에 커스텀 페이지 추가
      # 관리자 페이지에 action 추가

      admin.site.register(Bookmark, BookmarkOptions)
  2. github 업로드

    • github 계정에서 Repository를 생성한다.
    • 아무것도 추가 생성하지 않는다.(.gitignore, license)
    • pycharm 프로젝트로 돌아온다.
    • 의존성 리스트를 생성하지 않았다면 생성하도록 한다.

      1
      $ pip freeze > requirements.txt
    • .gitignore 파일을 생성한다.

      1
      2
      3
      4
      5
      6
      7
      # bookmark_project/.gitignore
      # .gitignore 파일 내용
      *.pyc
      *~
      /venv
      __pycache__
      db.sqlite3
    • 현재 프로젝트를 다음과 같은 순서로 github에 업로드한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      $ git init

      $ git add -A .

      $ git commit -m "first commit"

      # github에 만든 프로젝트의 주소를 가져옴
      $ git remote add origin https://github.com/JINUKK/Bookmark.git

      $ git push -u origin master
  3. pythonanywhere.com을 이용한 배포

    • 계정 생성 후, bash 진입
    • 다음과 같은 순서로 github에 업로드한 프로젝트를 가져온다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      $ git clone https://github.com/JINUKK/Bookmark.git

      $ cd Bookmark/

      # 가상 환경 적용
      $ virtualenv --python=python3.7 venv

      $ source venv/bin/activate

      # 의존성 리스트를 불러옴
      $ pip install -r requirements.txt

      $ python manage.py migrate

      $ python manage.py createsuperuser
    • bash 페이지에서 오른쪽 상단에 Web 페이지 열기

    • Wep app 시작하기(Manual Configuration 및 python3.7 선택)
    • Virtualenv 항목에서 경로 지정
      • bash 페이지에서 pwd 명령어를 이용하여 경로 보기
      • /home/[pythonanywhere-id]/Bookmark/venv
    • Code 항목에서 WSGI configuration file 수정

      • pycharm 프로젝트에서 config/wsgi.py 내용으로 변경
      • CSS를 다루기 위해 StaticFilesHandler도 추가
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        import os
        import sys

        path='/home/pythonanywhere-id/Bookmark'
        if path not in sys.path:
        sys.path.append(path)

        from django.core.wsgi import get_wsgi_application
        from django.contrib.staticfiles.handlers import StaticFilesHandler

        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')

        application = StaticFilesHandler(get_wsgi_application())
      • pycharm 프로젝트로 돌아와서 settings.py를 다음과 같이 수정한다.

        1
        2
        3
        DEBUG = False # 디버그를 보여줌. 사용자 입장에서는 안보이게 False로 처리

        ALLOWED_HOSTS = ['.pythonanywhere.com','localhost','127.0.0.1']
      • git에 add, commit, push를 진행한다.

        1
        2
        3
        4
        5
        $ git add -A .

        $ git commit -m "second commit"

        $ git push origin master
      • pythonanywhere의 bash로 돌아와서 git pull을 진행한다.

        1
        $ git pull
      • Reload id.pythonanywhere.com을 진행한 후, 사이트에 접속해본다.

Share