전체 페이지뷰

2017년 1월 17일 화요일

Blog photo앱 : Pillow Part.2

계속 이어서 코딩을 진행해봅니다.

URLconf 코딩

url 정의는 루트사이트인 mysite/urls.py와 개별 앱사이트인 photo/urls.py에 모두 작성합니다.

mysite부터 먼저 작업합니다.

(myvenv) D:\myDjango\mysite>subl urls.py


from django.conf.urls import include, url
from django.contrib import admin
from django.conf.urls.static import static #추가
from django.conf import settings  #추가
 
from mysite.views import HomeView  
 
 
urlpatterns = [ 
    url(r'^admin/', include(admin.site.urls)), 
    url(r'^$', HomeView.as_view(), name='home'), 
    url(r'^bookmark/', include('bookmark.urls', namespace='bookmark')), 
    url(r'^blog/', include('blog.urls', namespace='blog')),
    url(r'^photo/', include('photo.urls', namespace='photo')),  #추가
    ] + static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT) #추가
cs


정적 파일을 처리하는 뷰의 url패턴을 호출해 주는 static() 함수를 임포트하고,
settings.py 모듈에서 정의한 항목들에 대한 레퍼런스로서 settings를 임포트합니다.
포토앱의 url 패턴을 지정하고, namespace를 photo로 지정한 후,
기존  패턴에 static함수가 반환하는 URL패턴을 추가합니다.

photo의 urls.py를 작성합니다.

(myvenv) D:\myDjango\photo>subl urls.py


from django.conf.urls import url
from photo.views import *
 
urlpatterns = [
    # Example: /
    url(r'^$', AlbumLV.as_view(), name='index'),
 
    # Example: /album/, same as /
    url(r'^album/$', AlbumLV.as_view(), name='album_list'),
 
    # Example: /album/99/
    url(r'^album/(?P<pk>\d+)/$', AlbumDV.as_view(), name='album_detail'),
 
    # Example: /photo/99/
    url(r'^photo/(?P<pk>\d+)/$', PhotoDV.as_view(), name='photo_detail'),
]
cs



뷰 코딩하기

URLconf에서 지정한  클래스형 제너릭 뷰를 코딩합니다.

(myvenv) D:\myDjango\photo>subl views.py


from django.views.generic import ListView, DetailView
from photo.models import Album, Photo
 
# Create your views here.
 
class AlbumLV(ListView):
    model = Album
 
class AlbumDV(DetailView):
    model = Album
 
class PhotoDV(DetailView):
    model = Photo
cs


ListView와 DetailView를 상속받아 모델을 지정해 주는 것으로 끝납니다.


템플릿 코딩하기

album_list.html

앨범 정보와 앨번에 속한 사진 5개를 보여주는 화면입니다.
photo/templates/photo/ 디렉토리를 만들고 작성합니다.

(myvenv) D:\myDjango\photo>mkdir templates
(myvenv) D:\myDjango\photo>mkdir templates/photo
(myvenv) D:\myDjango\photo>cd templates\photo
(myvenv) D:\myDjango\photo\templates\photo>subl album_list.html


{% extends "base.html" %}
 
{% block title %}album_list.html{% endblock %}
 
{% load staticfiles %}
{% block extrastyle %}{% static "photo/photo.css" %}{% endblock %}
 
{% block content %}
<div id="content">
 
    {% for item in object_list %}
 
    <div class="clear_float">
        <h2 style="display:inline"><a href="{% url 'photo:album_detail' item.id %}"> {{ item.name }}</a></h2
        &emsp;<b><i>{{ item.description }}</i></b>
    </div>
 
    <hr/>
 
    <div class="album-list">
        {% for photo in item.photo_set.all|slice:":5" %}
        <div class="album-list-photo">
            <a href="{{ photo.get_absolute_url }}">
            <img class="thumbnail" src="{{ photo.image.thumb_url }}" />
            </a>
        </div>
        {% endfor %}
    </div>
 
    {% endfor %}
</div>
{% endblock %}
cs


AlbumLV에서 넘겨주는 object_list 객체를 순회하면서 썸네일을 출력해줍니다.
앨범 객체의 name과 description을 inline으로 한 줄에 출력해 줍니다.
"clear_float"는 photo.css에 정의할 예정입니다.


album_detail.html

(myvenv) D:\myDjango\photo\templates\photo>subl album_detail.html


{% extends "base.html" %}
 
{% block title %}album_detail.html{% endblock %}
 
{% load staticfiles %}
{% block extrastyle %}{% static "photo/photo.css" %}{% endblock %}
 
{% block content %}
<div id="content">
 
    <h2 style="display:inline">{{ object.name }}</h2>
    &emsp;<b><i>{{ object.description }}</i></b>
 
    <hr/>
 
    <div class="album-detail">
        {% for photo in object.photo_set.all %}
        <div class="album-detail-photo">
            <a href="{{ photo.get_absolute_url }}">
            <img class="thumbnail" src="{{ photo.image.thumb_url }}" />
            </a>
            <li>{{ photo.title }}</li>
            <li>{{ photo.upload_date|date:"Y-m-d" }}</li>
        </div>
        {% endfor %}
    </div>
 
</div>
{% endblock %}
cs


object.photo_set.all은 앨범객체에 들어있는 모든 사진 객체로 구성된 리스트입니다. 이 리스트를 순회하면서 url을 얻어와 썸네일과 그 정보를 출력해줍니다.

photo_detail.html

개별 사진에 대한 정보를 출력하는 곳입니다.

{% extends "base.html" %}
 
{% block title %}photo_detail.html{% endblock %}
 
{% load staticfiles %}
{% block extrastyle %}{% static "photo/photo.css" %}{% endblock %}
 
{% block content %}
<div id="content">
 
    <h2>{{ object.title }}</h2>
 
    <table class="photo-detail">
    <tr>
    <td>
        <a href="{{ object.image.url }}">
        <img style="max-width:100%" src="{{ object.image.url }}"/>
        </a>
    </td>
 
    <td>
    <ul>
        <li>Photo Description</li>
        {% if object.description %}<p>{{ object.description|linebreaks }}</p>
        {% else %}<p>(blank)</p>{% endif %}
        <li>Date Uploaded</li>
        <p>{{ object.upload_date }}</p>
        <li>Album Name</li>
        <p><a href="{% url 'photo:album_detail' object.album.id %}">{{ object.album.name }}</a></p>
    </ul>
    </td>
    </tr></table>
 
</div>
{% endblock %}
cs

이미지를 출력하고 사진 객체의 속성들을 화면에 출력해줍니다.

base.html

포토앱에서 사용하는 세개의 html을 작성했습니다. 기존 base.html 상단 메뉴의 Photo 버튼에 포토앱을 연결시키기만 하면 완료입니다.

<div id="menu">
    <li><a href="{% url 'home' %}">Home</a></li>  
    <li><a href="{% url 'bookmark:index' %}">Bookmark</a></li>
    <li><a href="{% url 'blog:index' %}">Blog</a></li>
    <li><a href="{% url 'photo:index' %}">Photo</a></li<!--수정-->
cs

중간 메뉴 항목을 찾아 Photo부분을 수정합니다.


스타일 시트 코딩

photo/static/photo 디렉토리를 만들고 photo.css 파일을 작성합니다.

(myvenv) D:\myDjango\photo>mkdir static
(myvenv) D:\myDjango\photo>mkdir static\photo
(myvenv) D:\myDjango\photo>cd static\photo
(myvenv) D:\myDjango\photo\static\photo>subl photo.css

/* album_list.html */
div.album-list {
    margin: 20px 50px;
}
div.album-list-photo {
    float: left;
    width: 150px;
    height: 180px;
}
/* album_detail.html */
div.album-detail {
    margin: 30px 10px;
}
div.album-detail-photo {
    float: left;
    width: 220px;
    height: 220px;
}
div.album-detail-photo > li {
    font-size: 10px;
    font-weight: bold;
    font-style: italic;
}
/* photo_detail.html */
table.photo-detail {
    margin: 30px 50px 0 50px;
    border: 1px solid #ccc;
    padding: 20px 20px;
}
table.photo-detail td {
    width: 50%;
}
table.photo-detail ul li {
    font-weight: bold;
}
table.photo-detail ul p {
    font-style: italic;
}
/* common */
img.thumbnail {
    border: 3px solid #ccc;
}
div.clear_float {
    clear: both;
}
cs

코딩을 마쳤으니 이제 사진과 설명 데이터를 입력해봅니다.
runserver를 실행하여 Admin으로 들어가 Albums의 Add로 사진을 추가합니다.

Photo버튼을 누르면 다음과 같은 모습이 나타납니다.

앨범제목을 누르면


사진을 클릭하면 개별 사진이 나타납니다.



이것으로 장고에 대한 포스팅은 마치겠습니다. 
지금까지가 김석훈 님의 파이썬 웹프로그래밍 실전편의 약 절반 정도 양인데,
이 정도로도 기초적인 웹프로그래밍에 대한 많은 지식을 얻을 수 있었습니다.
더 깊은 내용은 책이나 다른 사이트들을 참고 바랍니다.

댓글 없음:

댓글 쓰기