Skip to content

Commit

Permalink
feat(read stats): users should see their read stats:
Browse files Browse the repository at this point in the history
   -  user can view most recent 10 reads
[Finishes #164798223]
  • Loading branch information
ezrogha committed Apr 16, 2019
1 parent 8ec1930 commit 41115da
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 7 deletions.
24 changes: 24 additions & 0 deletions authors/apps/articles/migrations/0004_readingstats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.2 on 2019-04-15 21:41

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('articles', '0003_article_favorite'),
]

operations = [
migrations.CreateModel(
name='ReadingStats',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('article', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='articles.Article')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
4 changes: 3 additions & 1 deletion authors/apps/articles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,6 @@ class ArticleLikeDislike(models.Model):
createdAt = models.DateTimeField(auto_now_add=True)



class ReadingStats(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
article = models.ForeignKey(Article, on_delete=models.CASCADE, blank=True)
7 changes: 7 additions & 0 deletions authors/apps/articles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .models import Article
from authors.apps.comments.models import Comment
from authors.apps.comments.serializers import CommentDetailSerializer
from authors.apps.authentication.serializers import UserSerializer
from authors.apps.helpers.share_articles import share_articles_links


Expand Down Expand Up @@ -64,3 +65,9 @@ class Meta:
'article': {'write_only': True},
}


class ReadingStatsSerializer(serializers.ModelSerializer):
article = ArticleSerializer(read_only=True)
class Meta:
fields = ["article"]
model = models.ReadingStats
4 changes: 4 additions & 0 deletions authors/apps/articles/tests/test_articles.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ def test_favorite_list(self):
response2 = self.client.get(f'/api/users/articles/favorites', HTTP_AUTHORIZATION=user_token, format='json')
self.assertEqual(response2.status_code, status.HTTP_200_OK)

def test_read_stats(self):
user_token = self.create_user(test_data.test_user_data)
response2 = self.client.get(f'/api/users/articles/most-recent-reads', HTTP_AUTHORIZATION=user_token, format='json')
self.assertEqual(response2.status_code, status.HTTP_200_OK)

def test_article_contains_share_links(self):
"""
Expand Down
12 changes: 10 additions & 2 deletions authors/apps/articles/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.shortcuts import get_object_or_404, render
from rest_framework import generics ,status
from .models import Article, ArticleLikeDislike
from .models import Article, ArticleLikeDislike, ReadingStats
from authors.apps.profiles.models import Profile
from . import serializers
from rest_framework.response import Response
Expand Down Expand Up @@ -40,7 +40,7 @@ def get_serializer_context(self):
def create(self, request):
article = request.data

serializer = self.serializer_class(data=article, context={'request':self.request})
serializer = self.serializer_class(data=article, context=self.get_serializer_context())

author = Profile.objects.get(username=self.request.user.username)
serializer.is_valid(raise_exception=True)
Expand All @@ -61,6 +61,14 @@ class RetrieveUpdateDestroyArticle(generics.RetrieveUpdateDestroyAPIView):
serializer_class = serializers.ArticleSerializer
lookup_field = 'slug'


def get(self, request, *args, **kwargs):
user = request.user
article = self.get_object()
ReadingStats.objects.create(article=article, user=user)
serializer = serializers.ArticleSerializer(article, context=self.get_serializer_context())
return Response(serializer.data, status=status.HTTP_200_OK)




Expand Down
8 changes: 4 additions & 4 deletions authors/apps/authentication/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from .views import (
LoginAPIView, RegistrationAPIView,
UserRetrieveUpdateAPIView, FacebookAuthApiView,
GoogleAuthApiView, TwitterAuthApiView, VerifyUserAPIView, FavoritesList,
PasswordChangeView,PasswordResetView
GoogleAuthApiView, TwitterAuthApiView, VerifyUserAPIView, FavoritesList,
PasswordChangeView, PasswordResetView, ReadingStatsView
)

urlpatterns = [
Expand All @@ -17,6 +17,6 @@
path('users/verify/', VerifyUserAPIView.as_view(), name='verify-user'),
path('users/articles/favorites', FavoritesList.as_view(), name='favorites'),
path('users/password-reset/', PasswordResetView.as_view(), name='reset-password'),
path('users/reset/<str:token>/change/', PasswordChangeView.as_view(), name='password-change')

path('users/reset/<str:token>/change/', PasswordChangeView.as_view(), name='password-change'),
path('users/articles/most-recent-reads', ReadingStatsView.as_view(), name='read-stats'),
]
21 changes: 21 additions & 0 deletions authors/apps/authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from authors import settings
from authors.settings import SECRET_KEY

from authors.apps.articles.models import Article, ReadingStats
from authors.apps.articles import serializers, models

class RegistrationAPIView(GenericAPIView):
# Allow any user (authenticated or not) to hit this endpoint.
Expand Down Expand Up @@ -207,3 +209,22 @@ def put(self, request, *args, **kwargs):
{"error": "Passwords do not match"},
status=status.HTTP_400_BAD_REQUEST
)

class ReadingStatsView(generics.ListAPIView):
"""
The user should be able to see ten of their most recent reads
"""
permission_classes = [IsAuthenticated]
queryset = models.ReadingStats.objects.all()
serializer_class = serializers.ReadingStatsSerializer

def get_serializer_context(self):
return {
'request': self.request
}

def get(self, request):
current_user_id = request.user.id
user_recent_reads = reversed(ReadingStats.objects.filter(user_id=current_user_id).distinct('article_id')[:10])
serializer = self.serializer_class(user_recent_reads, context=self.get_serializer_context(), many=True)
return Response(serializer.data, status=status.HTTP_200_OK)

0 comments on commit 41115da

Please sign in to comment.