Class-based view

Class-based view로
PostList, PostDetail, PostCreate, PostDelete 뷰를 작성

post/views/post.py

from django.views import View

__all__ = (
    'PostList',
    'PostDetail',
    'PostDelete',
)


class PostList(View):
    pass


class PostDetail(View):
    pass


class PostDelete(View):
    pass

django_app/config/url.py

from django.conf.urls import url

from .. import views

app_name = 'post'
urlpatterns = [
    url(r'^$', views.PostList.as_view(), name='post-list'),
    url(r'^(?P<pk>[0-9]+)/$', views.PostDetail.as_view(), name='post-detail'),
    url(r'^(?P<pk>[0-9]+)/$', views.PostDelete.as_view(), name='post-delete'),
]

접속하면 클래스에 구현되어 있는게 없어 다음과 같은 로그가 출력된다.

[20/Mar/2017 14:31:54] "GET /post/ HTTP/1.1" 405 0
Method Not Allowed (GET): /post/

static, media 설정

기존 프로젝트의 설정을 가져와서 PostList가 작동하도록 구현
	- STATIC_DIR 경로 변수 지정
	- STATICFILES_DIRS 지정
	- 기존 프로젝트의 static 폴더 통째로 복사
	- .gitignore에 django_app/static/css/ 추가 (css 파일은 더 이상 소스코드에 포함되지 않음, SCSS 파일만 포함)
	- 기존 프로젝트의 tempaltes 폴더 통째로 복사
	- Templates 설정
	- PostList CBV에 get 메서드 작성 및 내부 쿼리 return

데이터 추가

admin에서 post 전체 삭제 후

1. 데이터 추가
- Postman으로 post 두개 만들고, 각각의 Post에 PostPhoto를 3개 추가
2. post_list.html에서 posts변수를 loop하며 각 post의 postphoto_set.all을 loop
- postphoto_set을 내부에서 loop하며 loop 아이템의 photo.url을 이용해 이미지 출력

templates/post/post_list.html

config/urls.py

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

자바스크립트

Swiper 설치

$ brew install bower
# pip freeze 같은 역할
$ bower init

# 자동으로 init에 추가
$ bower install jquery --save
$ bower install swiper --save

# 프로젝트에서 bower_components 폴더가 생긴 것 확인

config/setting.py

# Static path
BOWER_DIR = os.path.join(ROOT_DIR, 'bower_components')
STATIC_URL = '/static/'
STATIC_DIR = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = (
    STATIC_DIR,
    BOWER_DIR,
)

templates/common/base.html (참고 링크)

templates/post/post_list.html

ListView로 변경

post/views/post.py

class PostList(ListView):
    model = Post

templates/post/post_list.html

context 이름 변경

post/views/post.py

class PostList(ListView):
    model = Post
    context_object_name = 'posts'

templates/post/post_list.html

PostDetail View 구현 (DetailView)

post/views/post.py

class PostDetail(DetailView):
    model = Post

코드 분리

templates/post/include/post.html

생성 후 아래와 같이 작성

templates/post/post_list.html

templates/post/post_detail.html

comment 추가

comment create가 동작할 수 있도록 urls 및 뷰를 구현

post/models/comment.py

를 생성하고, 기존 models.py는 post.py로 이름을 변경한다.

from django.conf import settings
from django.db import models

from post.models.post import Post

__all__ = (
    'PostComment',
)


class PostComment(models.Model):
    post = models.ForeignKey(Post)
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    content = models.TextField()

    def __str__(self):
        return '{} comment (author: {})'.format(
            self.post_id,
            self.author_id,
        )

post/models/post.py

from django.conf import settings
from django.db import models

__all__ = (
    'Post',
    'PostPhoto',
)


class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL)
    created_date = models.DateTimeField(auto_now_add=True)


class PostPhoto(models.Model):
    post = models.ForeignKey(Post)
    photo = models.ImageField(upload_to='post')
    created_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        order_with_respect_to = 'post'

post/models/init.py

from .comment import *
from .post import *

post/urls/views.py

urlpatterns = [
	# ...
    url(r'^(?P<post_pk>[0-9]+)/comment/create/$', views.CommentCreate.as_view(), name='comment-create')
]

post/views/comment.py

@method_decorator(login_required, name='dispatch')
class CommentCreate(CreateView):
    model = PostComment
    fields = (
        # 'author',
        # 'post',
        'content',
    )

    def get_success_url(self):
        return reverse('post:post-detail', kwargs={'pk': self.kwargs['post_pk']})

    def form_valid(self, form):
        comment = form.save(commit=False)
        post_pk = self.kwargs['post_pk']
        post = Post.objects.get(pk=post_pk)
        author = self.request.user
        comment.post = post
        comment.author = author
        comment.save()
        return HttpResponseRedirect(self.get_success_url())

과제