1. ProjectApp 스스로 만들어보기
여태까지 했던 내용을 바탕으로 스스로 ProjectApp을 만들어본다. 대상 및 요구사항은 아래와 같다.
대상: projectapp - article 들을 담을 수 있는 폴더 같은 개념이다. project:artilce = 1:N
요구사항:
- Create, Detail, List View를 만든다.
- Create 시 login이 필요하다.
- Model의 fields = ['title', 'description', 'image', 'created_at']
위 사항들을 바탕으로 스스로 만들어본 페이지 사진
새로운 내용들
pagination option
기존에는 a link의 ? 앞에 {% url 'articleapp:list' %} 라는 문구가 있었는데, 이를 삭제했다. 이렇게 해서 list를 사용하는 페이지들 모두에서 pagination option을 공통으로 사용할 수 있게 된다.
<a href="?page={{ page_obj.number }}"
class="btn btn-secondary rounded_pill active">
{{ page_obj.number }}
</a>
truncatechars 옵션
프로젝트용 card를 표현하기 위해서 기존 snippets/card.html 외에 card_project.html을 추가하였다. 여기서 {{ }} 문법 내부의 | truncatechars 옵션을 보자. 이렇게 하면 project.title을 4글자까지 자르고, 나머지는 ...으로 표시해준다.(위 페이지 그림 참고)
<div style="text-align: center; display: block">
<img src="{{ project.image.url }}" alt="">
<div>
{{ project.title | truncatechars:5 }}
</div>
</div>
css의 object-fit 옵션
projectapp/list.html 에서 object-fit: cover 옵션을 사용했다. 이렇게 하면 .container가 정사각형이면 그에 맞게 사진을 정사각형으로 잘라서 배치해준다. 만약 이 옵션이 없는데 넣는 img가 정사각형이 아니라면 정사각형 .container 틀에 사진을 맞출려고 사진을 일그러뜨리게 된다.
.container img {
width: 7rem;
height: 7rem;
border-radius: 1rem;
object-fit: cover;
}
2. Project 페이지에 article List 넣기 : MultipleObjectMixin
이제 Project detail 페이지에 article list가 나오도록 한다.
Project : Article 연결
우선 1:N 관계로 연결해주기 위해서 연관관계의 주인인 Article의 model을 수정하고 migrate를 다시한다.
class Article(models.Model):
writer = models.ForeignKey(User, on_delete=models.SET_NULL, related_name='article', null=True)
project = models.ForeignKey(Project, on_delete=models.SET_NULL, related_name='article', null=True)
## 나머지 필드 생략
그리고 Article을 만들때, project 값도 넣을 수 있도록 ArticleCreationForm을 수정한다. (articleapp/create.html의 양식은 bootstrap의 {% form %}에 의해 자동 수정됨)
class ArticleCreationForm(ModelForm):
class Meta:
model = Article
fields = ['title', 'image', 'project', 'content']
project의 dropdown 메뉴는 실제 project 이름이 안뜨는데, bootstrap을 수정해줘야할 것 같다. 어떻게 하는지 정확히 모르겠다...
MultipleObjectMixin 적용
이제 list를 만들기 위해서 MultipleObjectMixin을 적용한다. commentapp에서 했던 것처럼, article.comment.all로 모두 가져와도 되지만, 이렇게하면 아무런 옵션없이 무조건 다 가져오는게 돼버린다. 여러 옵션들을 제공하는 MultipleObjectMixin을 이용해서 list를 가져와보자.
projectapp/views.py:ProjectDetailView
MultipleObjectMixin을 상속받아서 paginate_by 옵션이 적용가능하게 되었다. 그리고 get_context_data 메서드를 불러와서 list로 사용할 객체를 Article 중에서 project가 detailView에서 가져오는 proejct object만 filtering 하도록 지정해주었다.
class ProjectDetailView(DetailView, MultipleObjectMixin):
model = Project
context_object_name = 'target_project'
template_name = 'projectapp/detail.html'
paginate_by = 5
def get_context_data(self, **kwargs):
object_list = Article.objects.filter(project=self.get_object())
return super(ProjectDetailView, self).get_context_data(object_list=object_list, **kwargs)
projectapp에 적용
마지막으로 list를 적용한다. 위에서 정의한 object_list를 활용한다.
templates/snippets/list_fragment.html
공통으로 활용하기 위해서 list_fragment를 만든다. 이 코드는 articleapp/list.html의 파일을 그대로 복사해서 사용하며, 중복되는 extends, block content 구문만 삭제한다.
projectapp/detail.html의 일부
그리고 이 코드를 활용해서 projectapp/detail.html에 include ... with 구문으로 불러온다. list_fragment에서의 article_list가 view에서 detail.html로 전달되는 object_list가 되도록 하기 위해서 with 구문을 아래처럼 작성했다.
<hr>
<div>
{% include 'snippets/list_fragment.html' with article_list=object_list %}
</div>
</div>
{% endblock %}
accountapp에 적용
마지막으로 accountapp/AccountDetailView에서도 로그인한 사용자가 만든 article의 list가 조회될 수 있도록 MultipleObjectMixin을 적용해준다.
accountapp/AccountDetailView
class AccountDetailView(DetailView, MultipleObjectMixin):
model = User
context_object_name = 'target_user'
template_name = 'accountapp/detail.html'
paginate_by = 10
def get_context_data(self, **kwargs):
object_list = Article.objects.filter(writer=self.get_object())
return super(AccountDetailView, self).get_context_data(object_list=object_list, **kwargs)
accountapp/detail.html 일부
<div>
{% include 'snippets/list_fragment.html' with article_list=object_list %}
</div>
</div>
{% endblock %}
아래 article들이 왜 오른쪽으로 치우치는지는 잘 모르겠다.. 시간이 허용한다면 다음에 알아보자 ㅠ
참조
1. 작정하고 장고! Django로 Pinterest 따라만들기 : 바닥부터 배포까지-박형석님 인프런 강의
'Programming-[Backend] > Django' 카테고리의 다른 글
Django로 Pinterest 따라 만들기-16. WYSIWYG 적용, 프로젝트 다듬기 (0) | 2022.06.14 |
---|---|
Django로 Pinterest 따라 만들기-15. Subsrcibe, RedirectView, Field Lookup, queryset (0) | 2022.06.14 |
Django로 Pinterest 따라 만들기-13. MobileResponsive Layout 구현 (0) | 2022.06.13 |
Django로 Pinterest 따라 만들기-12. ListView/Pagination, Mixin, CommentApp 구현 (0) | 2022.06.11 |
Django로 Pinterest 따라 만들기-11. MagicGrid 활용, ArticleApp CRUD 완성하기 (0) | 2022.06.10 |