MultipleObjectMixin을 통한 ProjectApp 마무리
여러개의 article을 하나의 project로 묶어주는 작업
project = models.ForeignKey(Project, on_delete=models.SET_NULL, related_name='article', null=True)
HTML
복사
게시글을 작성했을 때 어느 게시판에 쓸 지 결정해주기 위해
articleapp → forms.py → ArticleCreationForm class의 fields에 ‘project’ 항목 추가
아직 게시판이 있어도 그 안에 속한 게시글이 보이지 않음!
views.py안에서 새로운 Mixin 사용
ProjectDetailView class에서 MultipleObjectMixin을 상속받아서 다음과 같은 함수 구현
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
복사
snippets → list_fragment를 만들고 projectapp → detail.html에 다음과 같은 코드 추가
{% include 'snippets/list_fragment.html' with article_list=object_list %}
HTML
복사
내가 쓴 글 모아보기도 동일한 방식으로 진행
RedirectView를 통한 SubscribeApp 시작
구독 버튼의 경우 딱히 필요한 정보 없음, 요청을 받으면 처리할 것만 하고 Redirect
어떤 유저와 어떤 프로젝트 그 쌍이 가지는 구독정보를 하나로 만듬
class Subscription(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='subscription')
project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='subscription')
class Meta:
unique_together = ('user', 'project')
Python
복사
@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'))
#project pk를 갖고 있는 project를 찾는데 없으면 페이지를 찾을 수 없다는 response를 되돌려 준다
user = self.request.user
#위의 2가지 정보로 subscription을 찾음
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
복사
구독버튼 생성
<div class="text-center mb-5">
{% if user.is_authenticated %}
<a href="{% url 'subscribeapp:subscribe' %}?project_pk={{ target_project.pk }}"
class="btn btn-primary rounded-pill px-4">
Subscribe
</a>
{% endif %}
</div>
HTML
복사
버튼을 눌렀는데 redirect는 하는데 아무 반응이 없음
지금 접속해있는 유저가 이 게시판에 대한 구독정보가 있는지 없는지 확인
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
복사
projectapp → detail.html에서 구독하지 않았을 경우에 대한 행동 생성 → 버튼 색 수정
Field Lookup을 사용한 구독 페이지 구현
Model.objects.filter(pk=xxx, user=xxx)
object의 filter에 특정 조건을 넣었는데 이 때, AND function 사용 → pk와 user의 어떤 값 둘 다 만족
그렇다면 OR function은? WHERE function in SQL?
1.
유저가 구독하고 있는 프로젝트들 확인
2.
그 프로젝트 안의 모든 게시글 가져오기
앞으로 이렇게 바꾸어 씀
Model.objects.filter(project__in=projects)
SQL에서 SELECT ... WHERE project IN(...); 과 대칭임
Field Lookup
복잡한 DB query를 사용자가 구현할 수 있도록 함
__ 이렇게 더블 언더스코어를 넣은 명령어들
@method_decorator(login_required,'get')
class SubscriptionListView(ListView):
model = Article
context_object_name = 'article/list'
template_name = 'subscribeapp/list.html'
paginate_by = 5
Python
복사