41강. MultipleObjectMixin을 통한 ProjectApp 마무리
Project와 Article을 연결하는 작업, 그리고 MultipleObjectMixin 을 이용해서 ProjectApp 의 Detail 페이지를 마무리 하고, 같은 방식으로 AccountApp 의 디테일 페이지도 수정합니다.
articleapp/models에 추가
project = models.ForeignKey(Project, on_delete=models.SET_NULL, related_name='article', null=True)
forms에 추가 'project',
projectapp/veiws.py 에 ProjectDetailView 수정.
class ProjectDetailView(DetailView, MultipleObjectMixin):
model = Project
context_object_name = 'target_project'
template_name = 'projectapp/detail.html'
paginate_by = 25
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)
Python
복사
projectapp/detail.html 수정
{% extends 'base.html' %}
{% block content %}
<div>
<div style="text-align: center; max-width: 500px; margin: 4rem auto;">
<img src="{{target_user.profile.image.url }}" alt=""
style="height: 12rem; width: 12rem; border-radius: 20rem; margin-bottom: 2rem; object-fit: cover;">
<h2 style="font-family: 'NanumSquareB'">
{{ target_project.title }}
</h2>
<h5 style="margin-bottom: 3rem;">
{{ target_project.description }}
</h5>
</div>
<div>
{% include 'snippets/list_fragment.html' with article_list=object_list %}
</div>
</div>
{% endblock %}
HTML
복사
templates/snippets/list_fragment.html 생성
{% load static %}
<style>
.container {
padding: 0;
margin: 0, auto;
}
.container a {
width: 45%;
max-width: 250px;
}
.container div {
display: flex;
justify-content: center;
align-items: center;
border-radius: 1rem;
}
.container img {
width: 100%;
border-radius: 1rem;
}
</style>
{% if article_list %}
<div class="container">
{% for article in article_list %}
<a href="{% url 'articleapp:dtail' pk=article.pk %}">
{% include 'snippets/card.html' with article=article %}
</a>
{% endfor %}
</div>
<script src="{% static 'js/magicgrid.js' %}"></script>
{% else %}
<div class="text-center">
<h1>No Articles YET!</h1>
</div>
{% endif %}
{% include 'snippets/pagination.html' with page_obj=page_obj %}
<div style="text-align: center">
<a href="{% url 'articleapp:create' %}" class="btn btn-dark rounded-pill mt-3 mb-3 px-3">
Create Article
</a>
</div>
HTML
복사
accountapp/views.py 에 AccountDetailView 수정
class AccountDetailView(DetailView, MultipleObjectMixin):
model = User
context_object_name = 'target_user'
template_name = 'accoutapp/detail.html'
paginate_by = 25
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)
Python
복사
accountapp/detail.html에 추가
<div>
{% include 'snippets/list_fragment.html' with article_list=object_list %}
</div>
HTML
복사
git add .
git commit -m “django course 41 commit”
Subscribeapp Implementation
42강. RedirectView을 통한 SubscribeApp 시작
RedirectView 기반의 구독 시스템, 즉 SubscribeApp을 만들어봅니다.
‘subscribeapp’ 추가
path('subscribe/', include('subscribeapp.urls')), url 추가
subscribeapp/urls.py 만들기
from django.urls import path
app_name = 'subscribeapp'
urlpatterns = [
]
Python
복사
views.py 작성
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, get_object_or_404
# Create your views here.
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.generic import RedirectView
from projectapp.models import Project
from subscribeapp.models import Subscription
@method_decorator(login_required, 'get')
class SubscriptionView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
return reverse('projectapp:detail', kwargs={'pk': self.request.GET.get('project_pk')})
def get(self, request, *args, **kwargs):
project = get_object_or_404(Project, pk=self.request.GET.get('project_pk'))
user = self.request.user
subscription = Subscription.objects.filter(user=user, project=project)
if subscription.exists():
subscription.delete()
else:
Subscription(user=user, project=project).save()
return super(SubscriptionView, self).get(request, *args, **kwargs)
Python
복사
urls.py 수정
from django.urls import path
from subscribeapp.views import SubscriptionView
app_name = 'subscribeapp'
urlpatterns = [
path('subscribe/', SubscriptionView.as_view(), name='subscribe')
]
Python
복사
projectapp/detail.html 에 코드 추가
<div class="text-center mb-4">
{% if user.is_authenticated %}
{% if not subscription %}
<a href="{% url 'subscribeapp:subscribe' %}?project_pk={{ target_project.pk }}"
class="btn btn-primary rounded-pill px-4">
Subscribe
</a>
{% else %}
<a href="{% url 'subscribeapp:subscribe' %}?project_pk={{ target_project.pk }}"
class="btn btn-dark rounded-pill px-4">
Unsubscribe
</a>
{% endif %}
{% endif %}
</div>
HTML
복사
projectapp/views.py ProjectDetailView 수정.
class ProjectDetailView(DetailView, MultipleObjectMixin):
model = Project
context_object_name = 'target_project'
template_name = 'projectapp/detail.html'
paginate_by = 25
def get_context_data(self, **kwargs):
project = self.object
user = self.request.user
if user.is_authenticated:
subscription = Subscription.objects.filter(user=user, project=project)
object_list = Article.objects.filter(project=self.get_object())
return super(ProjectDetailView, self).get_context_data(object_list=object_list,
subscription=subscription,
**kwargs)
Python
복사
git add .
git commit -m “django course 42 commit”
43강. Field Lookup을 사용한 구독 페이지 구현
장고에서 제공하는 DB Query를 위한 기능, Field Lookup을 사용하여 사용자가 구독한 게시판의 게시글만 볼 수 있는 구독페이지를 만들어봅니다.
1.
Find user Subscripted projects
2.
Find articles in projects
1.
Find user Subscripted projects
2.
Find articles in projects
subscribeapp/views.py 에 코드 추가
@method_decorator(login_required, 'get')
class SubscriptionListView(ListView):
model = Article
context_object_name = 'article_list'
template_name = 'subscribeapp/list.html'
paginate_by = 5
def get_queryset(self):
projects = Subscription.objects.filter(user=self.request.user).values_list('project')
article_list = Article.objects.filter(project__in=projects)
return article_list
Python
복사
subscribeapp/templates/subscribeapp/list.html 생성
{% extends 'base.html' %}
{% block content %}
<div>
{% include 'snippets/list_fragment.html' with article_list=article_list %}
</div>
{% endblock %}
HTML
복사
urls에 추가
path('list/', SubscriptionListView.as_view(), name='list'),
header.html에 추가
<a href="{% url 'subscribeapp:list' %}" class="pragmatic_header_nav">
<span>Subscription</span>
</a>
HTML
복사
git add .
git commit -m "django course 43 commit”