From f338f3f5b2cbf1c7dd564076eb64bf1b7314ac00 Mon Sep 17 00:00:00 2001 From: Bo Lopker Date: Wed, 13 Jan 2021 23:08:58 -0800 Subject: [PATCH] Fix #8: allow users to favorite articles --- articles/views.py | 46 +++++++++++++++++++++++++-- realworld/settings.py | 3 +- realworld/urls.py | 5 +++ templates/articles/detail.html | 14 ++++---- templates/articles/favorite.html | 34 ++++++++++++++++++++ templates/articles/favorite_mini.html | 22 +++++++++++++ templates/articles/list.html | 13 +++----- templates/base.html | 7 +++- 8 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 templates/articles/favorite.html create mode 100644 templates/articles/favorite_mini.html diff --git a/articles/views.py b/articles/views.py index 171106d..efd5f91 100644 --- a/articles/views.py +++ b/articles/views.py @@ -1,7 +1,9 @@ -from django.shortcuts import get_object_or_404 +from django.http.response import Http404 +from django.shortcuts import get_object_or_404, redirect +from django.conf import settings from django.urls import reverse_lazy from django.shortcuts import render -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, JsonResponse from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView, UpdateView @@ -12,7 +14,8 @@ def view(req, slug): - return render(req, "articles/detail.html") + article = get_object_or_404(Article, slug=slug) + return render(req, "articles/detail.html", {"article": article}) class ListArticle(ListView): @@ -178,3 +181,40 @@ def form_valid(self, form): """ self.object = form.save(self.request.user) return HttpResponseRedirect(self.get_success_url(), status=303) + + +def favorite_article(request, slug): + template = "articles/favorite.html" + if request.GET.get("mini", None): + template = "articles/favorite_mini.html" + + query = Article.objects.annotate(favorited_by__count=Count("favorited_by")) + article = get_object_or_404(query, slug=slug) + + favorited = False + if request.user.is_authenticated: + favorited = request.user.profile.has_favorited(article) + + if request.method == "POST" and request.user.is_authenticated: + if favorited: + request.user.profile.unfavorite(article) + else: + request.user.profile.favorite(article) + favorited = not favorited + + active_class = "btn-outline-primary" + if favorited: + active_class = "btn-primary" + + # refresh counts + article = get_object_or_404(query, slug=slug) + + return render( + request, + template, + context={ + "article": article, + "active_class": active_class, + "favorited": favorited, + }, + ) diff --git a/realworld/settings.py b/realworld/settings.py index 03fff16..90d8e78 100644 --- a/realworld/settings.py +++ b/realworld/settings.py @@ -117,12 +117,11 @@ USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ STATIC_URL = "/static/" -STATICFILES_DIRS = [] +# STATICFILES_DIRS = ["assets"] STATIC_ROOT = BASE_DIR / "assets" diff --git a/realworld/urls.py b/realworld/urls.py index 29e301f..8223de9 100644 --- a/realworld/urls.py +++ b/realworld/urls.py @@ -24,6 +24,11 @@ path("", home_views.index, name="index"), path("article//", articles_views.view, name="article_view"), path("article/", articles_views.ListArticle.as_view(), name="article_list"), + path( + "article//favorite/", + articles_views.favorite_article, + name="article_favorite", + ), path( "editor//", articles_views.EditArticle.as_view(), name="article_edit" ), diff --git a/templates/articles/detail.html b/templates/articles/detail.html index 6b274b9..c502bb2 100644 --- a/templates/articles/detail.html +++ b/templates/articles/detail.html @@ -15,10 +15,9 @@

How to build webapps that scale

  Follow Eric Simons (10)    - + @@ -50,10 +49,9 @@

Introducing RealWorld.

  Follow Eric Simons (10)   - + diff --git a/templates/articles/favorite.html b/templates/articles/favorite.html new file mode 100644 index 0000000..da2c211 --- /dev/null +++ b/templates/articles/favorite.html @@ -0,0 +1,34 @@ + + {% if request.method == 'POST' %} + + + {% else %} {% if request.user.is_authenticated %} +
+ {% csrf_token %} + +
+ {% else %} + + +   Favorite Post + ({{ article.favorited_by__count }}) + + {% endif %} {% endif %} +
diff --git a/templates/articles/favorite_mini.html b/templates/articles/favorite_mini.html new file mode 100644 index 0000000..f4bb995 --- /dev/null +++ b/templates/articles/favorite_mini.html @@ -0,0 +1,22 @@ + + {% if request.user.is_authenticated %} +
+ {% csrf_token %} + +
+ {% else %} + + {{ article.favorited_by__count }} + + {% endif %} +
diff --git a/templates/articles/list.html b/templates/articles/list.html index d47141e..f3bffb7 100644 --- a/templates/articles/list.html +++ b/templates/articles/list.html @@ -31,9 +31,11 @@ {{ article.created_at }} - + + {{ article.title }} > {% endif %} -
diff --git a/templates/base.html b/templates/base.html index 2cb1dfb..68e4d9d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -18,10 +18,15 @@ +