- Subscribeapp - 구독기능 구현
$ python manage.py startapp subscribeapp
# pragmatic\urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accountapp.urls')),
path('profiles/', include('profileapp.urls')),
path('articles/', include('articleapp.urls')),
path('comments/', include('commentapp.urls')),
path('projects/', include('projectapp.urls')),
path('subscribes/', include('subscribeapp.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
# pragmatic\settings.py
# ...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrap4',
'profileapp',
'accountapp',
'articleapp',
'commentapp',
'projectapp',
'subscribeapp',
]
# ...
# subscribeapp\models.py
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')
# subscribeapp\views.py
@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 manage.py makemigrations
$ python manage.py migrate
<!-- projectapp\detail.html -->
{% extends 'base.html' %}
{% block content %}
<div>
<div style="text-align: center; max-width: 500px; margin: 4rem auto;">
<img src="{{ target_project.image.url }}" alt=""
style="height: 12rem; width 12rem; border-radius: 20rem; margin-bottom: 2rem; object-fit: cover;">
<h2 style="font-family: 'NnumSquareB'">
{{ target_project.title }}
</h2>
<h5 style="margin-bottom: 3rem;">
{{ target_project.description }}
</h5>
</div>
<div class="text-center">
{% 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>
<div>
{% include 'projectapp/snippets/list_fragment.html' with article_list=object_list %}
</div>
</div>
{% endblock %}
# subscribeapp\urls.py
app_name = 'subscribeapp'
urlpatterns = [
path('subscribe/', SubscriptionView.as_view(), name='subscribe'),
]
# projectapp\views.py
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.object.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)
<!-- projectapp\detail.html -->
{% extends 'base.html' %}
{% block content %}
<div>
<div style="text-align: center; max-width: 500px; margin: 4rem auto;">
<img src="{{ target_project.image.url }}" alt=""
style="height: 12rem; width 12rem; border-radius: 20rem; margin-bottom: 2rem; object-fit: cover;">
<h2 style="font-family: 'NnumSquareB'">
{{ target_project.title }}
</h2>
<h5 style="margin-bottom: 3rem;">
{{ target_project.description }}
</h5>
</div>
<div class="text-center">
{% 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-primary rounded-pill px-4">
Unsubscribe
</a>
{% endif %}
{% endif %}
</div>
<div>
{% include 'projectapp/snippets/list_fragment.html' with article_list=object_list %}
</div>
</div>
{% endblock %}