------------------------------------------------------------------------------------


< 장고걸스 튜토리얼(djangogirls tutorial) 실습 - 기본 >


[ PC 개발 환경 셋업(Develop Environment Setup) ]


* install python( C:\에 설치, add path 옵션 선택)

 - download&install : https://www.anaconda.com/download

 - version 확인 : python --version

* 가상환경 (Virtual environment 설치; C:\djangogirls 또는 D:\djangogirls 폴더 만들어서 그 밑에 설치, D가 있다면 D 추천)

 - djangogirls folder(directory) 만들기 : mkdir djangogirls

 - Window : python -m venv myvenv

 - Linux/OS-X : python -m venv myvenv

* 가상환경 활성화(Working Dir : D:\djangogirls) ; 활성화 명령 후 기본 경로 앞에 접두어 (myvenv) 붙으면 activation OK!

 - Winsdow : myvenv\Scripts\activate

 - Linux/OS-X : source myvenv\bin\activate

* 가상환경 불활성화 : close cmd window or 'deactivate'

* Working Dir 밑에 여러개의 myvenv 가상환경 설치가 가능은 하지만 보통은 한 프로젝트에 1개의 가상환경만 설치함. 따라서, 복수의 가상환경 필요시 Working Dir 를 별도로 만들어주는게 바람직함.

* install django (가상환경 활성화 시킨 후 django를 설치해야 django가 가상환경 폴더내에 설치됨.)

 - D:\djangogirls --> myvenv\Scripts\activate

 - pip install "django<2" (맥에서는 pip3) ; version 2 미만 버젼으로 설치(실습 호환성을 위해)

 - django-admin --version

* 중요 : django 설치 후 pip version upgrade 를 하라는 안내가 나오는 경우가 있는데, 이 때 python -m 을 생략하면 pip 삭제까지만 되고, 신규 pip 설치시 오류 발생. (즉, pip 자신이 자신을 삭제하고, 재설치 하려니 발생하는 permision 오류인 듯) --> pip 에 대한 upgrade시는 가상환경 밖의 python의 pip를 이용해야 함.

* 가상환경 폴더명을 변경해도 내부적으로는 변경전 이름으로 세팅되어 있으므로 변경하지 않는게 바람직함.

* install source code editor : Visual Studio Code

 - Editor 종류

   Visual Studio Code(VScode, MS에서 제작)

   Atom(Github에서 제작)

   Sublime text(Python으로 제작됨)

   PyCharm : python 사용자들이 많이 사용하기는 하나 사용법이 복잡, 초보에게는 부적합.

 - VScode설치 : https://code.visualstudio.com --> download for windows

   (옵션들 모두 체크해서 설치 --> 설치후 폴더에서 마우스 우클릭 'open with code' 사용 가능)

 - VScode extention 설치 : VScode 실행 --> 좌측 맨 아래 버튼 --> 상단에 검색

   anaconda extention pack --> install --> reload

   powershell --> install --> reload

   python --> install --> reload

   django template --> install --> reload

 - 환경설정 ; file -preference-settins 의 code 중괄호 안에 아래 코드 추가 --> 저장


"python.linting.pylintArgs": [ 

"--load-plugins", "pylint_django"

 - 표시언어 변경 : F1(view-command palette) --> display --> Configure Display Language --> ko or en --> save --> reload

]

* Jupyter Notebook 설치 (for python 실습)

 - cmd 창 초기 경로에서 pip install "ipython[notebook]" --> jupyter --version

 - 실행 : D:\djangogirls>jupyter notebook ( D:\djangogirls 밑에 실습 파일이 만들어지게 됨.)

 - new --> python3 --> 상단에서 파일명 변경 --> code 입력 후 run or shift+enter 로 code 실행


-------------------------------------------------------------------------------------------------------------


[ Django 초기 setup ]


* 장고 버젼(django version) 확인 : (myvenv) d:\djangogirls>django-admin --version

1.11.15

* 프로젝트 디렉토리(project drectory) 생성 : (myvenv) d:\djangogirls>django-admin startproject mysite

* settings.py 확인 및 수정 

TIME_ZONE =  'UTC' --> 'Asia/Seoul'

STSTIC_ROOT = os.path.join(BASE_DIR, 'static')   # 마지막 줄에 추가

DEBUG = True   # 프로젝트 수행시는 True, 실제 서비스 hosting 시는 False

ALLOWED_HOSTS = ['*']   # 모든 host ip address 허용

* 장고 도움말(Django Help) 확인 : (myvenv) d:\djangogirls\mysite>python manage.py --help

* 마이그레이션 실행 : (myvenv) d:\djangogirls\mysite>python manage.py migrate

* 장고 서버(django server) 실행 : (myvenv) d:\djangogirls\mysite>python manage.py runserver

 --> 127.0.0.1:8000 or localhost:8000 으로 접속 확인

* 컴퓨터 이름이 한글인 경우 UnicodeDecodeError 발생

 - 대처 : (myvenv) d:\djangogirls\mysite>python manage.py runserver 0:8000 또는

(myvenv) d:\djangogirls\mysite>python manage.py runserver 0.0.0.0:8000

 --> 127.0.0.1:8000 or localhost:8000 으로 접속 확인


-------------------------------------------------------------------------------------------------------------


[ 장고 코딩 시작(Start Django Coding) ]


* Django Model : data base table을 django 에서 정의하는 방법

* table 구성 : 

table name : Post(게시글)

cloumn name : title(제목), text(내용), author(글쓴이), created_date(작성일), published_date(게시일)

* 장고 앱 생성(make django app) : (myvenv) D:\djangogirls\mysite>python manage.py startapp blog

 - settings.py - INSTALLED-APPS 에 blog app 등록

INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'blog',

]

*  장고 모델 작성(django model) ; blog/models.py 를 아래 내용으로 수정

from django.db import models

from django.utils import timezone



class Post(models.Model):

    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)

    title = models.CharField(max_length=200)

    text = models.TextField()

    created_date = models.DateTimeField(default=timezone.now)

    published_date = models.DateTimeField(blank=True, null=True)


    def publish(self):

        self.published_date = timezone.now()

        self.save()


    def __str__(self):

        return self.title

 - class POST type의 특정 변수(title)에 대한 문자열 표현이 필요할 때는 under bar 2개로 __str__ 식으로 표현.

 - 명명법(아래 어느 방식으로 사용해도 무방함)

   java, c#) (camel case) ; calculateAveragePrice, CalculateAveragePrice (class name)

   python : calculate_average_price ; 이때는 소문자로만!

 - 마이그레이션 파일 생성(makemigrations) : (myvenv) D:\djangogirls\mysite>python manage.py makemigrations blog

 - 마이그레이션 실행(migrate) : (myvenv) D:\djangogirls\mysite>python manage.py migrate blog

* 장고 관리자(django-admin)으로 데이타 관리(data manage)하기

 - 관리자 화면을 한국어로 변경 : setting.py - LANGUAGE_CODE = 'en-us' --> 'ko'

 - models.py 에서 만든 table(POST class)을 django-admin page에 등록

from django.contrib import admin

from .models import Post


admin.site.register(Post)

 - 장고 관리자(superuser) 생성 : D:\djangogirls\mysite>python manage.py createsuperuser

Username : testadmin, PW : aaaa1111

* 장고 urls.py

 - 정규표현식(regular expressions) : ^(문자열 시작), $(문자열 끝), \d(숫자)

 - mysite/urls.py

from django.conf.urls import include, url

from django.contrib import admin



urlpatterns = [

    url(r'^admin/', admin.site.urls),

    url(r'', include('blog.urls')),

]

 - blog.urls.py

from django.conf.urls import url

from . import views


urlpatterns = [

    url(r'^$', views.post_list, name='post_list'),

]

* 장고 blog/views.py

from django.shortcuts import render


def post_list(request):

    return render(request, 'blog/post_list.html', {})

* 장고 template ; blog/templates/blog/post_list.html

<html>

    <head>

        <title>Django Girls blog</title>

    </head>

    <body>

        <div>

            <h1><a href="">Django Girls Blog</a></h1>

        </div>


        <div>

            <p>published: 14.06.2014, 12:14</p>

            <h2><a href="">My first post</a></h2>

            <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>

        </div>


        <div>

            <p>published: 14.06.2014, 12:14</p>

            <h2><a href="">My second post</a></h2>

            <p>Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut f.</p>

        </div>

    </body>

</html>

 - <em>text</em> : 텍스트 기울기(italic)

* django ORM & queryset

python manage.py shell

from blog.models import Post

from django.contrib.auth.models import User

Post.objects.all()

me = User.objects.first() # or

me = User.objects.get(username='testadmin')

Post.objects.create(author=me, title='Sample title', text='Test')

Post.objects.all()

Post.objects.filter(author=me)

Post.objects.filter(title__contains='title')

from django.utils import timezone

timezone.now()

post = Post.objects.get(title="Sample title")

post.publish()

Post.objects.filter(published_date__lte=timezone.now())

Post.objects.order_by('created_date')

Post.objects.order_by('-created_date')

Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')

exit()

* 기타 : pip install ipython --> shell 실행시 jupyter notebook 과 비슷한 cli를 보여줌.(tab 자동완성도 지원)

* 템플릿(template) 동적 데이터 ; view.py 수정해서 template 파일에 데이터 전달

 - from 다음에 있는 마침표(.)는 현재 디렉토리 또는 애플리케이션을 의미

from django.shortcuts import render

from django.utils import timezone

from .models import Post


def post_list(request):

    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')

    return render(request, 'blog/post_list.html', {'posts': posts})

* 템플릿(template) 확장 ; veiws.py 에서 전달받을 데이터를 template에 표시

 - blog/post_list.html

{% extends 'blog/base.html' %}


{% block content %}

    {% for post in posts %}

        <div class="post">

            <div class="date">

                {{ post.published_date }}

            </div>

            <h1><a href="">{{ post.title }}</a></h1>

            <p>{{ post.text|linebreaksbr }}</p>   # linebreaks : P tag로 줄바꿈됨.(better)

        </div>

    {% endfor %}

{% endblock %}

 - blog/base.html

<html>

    <head>

        <title>Django Girls blog</title>

    </head>

    <body>

        <div class="page-header">

            <h1><a href="/">Django Girls Blog</a></h1>

        </div>

        <div class="content container">

            <div class="row">

                <div class="col-md-8">

                {% block content %}

                {% endblock %}

                </div>

            </div>

        </div>

    </body>

</html>

* CSS ; base.html

{% load static %}

<html>

    <head>

        <title>Django Girls blog</title>

        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

        <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

        <link rel="stylesheet" href="{% static 'blog/blog.css' %}">

    </head>

    <body>

        <div class="page-header">

            <h1><a href="/">Django Girls Blog</a></h1>

        </div>

        <div class="content container">

            <div class="row">

                <div class="col-md-8">

                {% block content %}

                {% endblock %}

                </div>

            </div>

        </div>

    </body>

</html>


* Application 확장

 - blog/views.py

from django.shortcuts import render, get_object_or_404

from django.utils import timezone

from .models import Post


def post_list(request):

    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')

    return render(request, 'blog/post_list.html', {'posts': posts})


def post_detail(request, pk):

    post = get_object_or_404(Post, pk=pk)

    return render(request, 'blog/post_detail.html', {'post': post})

 - blog/post_detail.html

{% extends 'blog/base.html' %}


{% block content %}

    <div class="post">

        {% if post.published_date %}

            <div class="date">

                {{ post.published_date }}

            </div>

        {% endif %}

        <h1>{{ post.title }}</h1>

        <p>{{ post.text|linebreaksbr }}</p>

    </div>

{% endblock %}


* django 폼 : 생략


-------------------------------------------------------------------------------------------------------------


[ 장고 배포(Deploy Django) ]


* 배포준비 : 생략

* Python anywhere에 배포하기 : 생략


-- 참고 --

* 장고 template 에서

 - 앞 10글자만 보이기 : {{writing.content|truncatechars:10}}

 - 개행 적용 : {{writing.content|linebreaksbr}}


-----------------------------------------------------------------------------------------------------------------------------



+ Recent posts