From 80a691bf9fffdcda9cfe537d79dda7dfbcf3e881 Mon Sep 17 00:00:00 2001 From: Ryan Noelk Date: Fri, 8 Mar 2019 16:21:09 -0500 Subject: [PATCH] Feat/menu redo (#27) * adding stats endpoint from API. * removing end date and auto updating complete date --- v1/menu/migrations/0010_auto_20190308_1254.py | 22 ++++++++++++ v1/menu/models.py | 3 +- v1/menu/serializers.py | 15 ++++++-- v1/menu/urls.py | 9 +++-- v1/menu/views.py | 34 +++++++++++++++++-- 5 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 v1/menu/migrations/0010_auto_20190308_1254.py diff --git a/v1/menu/migrations/0010_auto_20190308_1254.py b/v1/menu/migrations/0010_auto_20190308_1254.py new file mode 100644 index 0000000..e176a25 --- /dev/null +++ b/v1/menu/migrations/0010_auto_20190308_1254.py @@ -0,0 +1,22 @@ +# Generated by Django 2.1.7 on 2019-03-08 12:54 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('menu', '0009_auto_20190301_1353'), + ] + + operations = [ + migrations.RenameField( + model_name='menuitem', + old_name='end_date', + new_name='complete_date', + ), + migrations.RemoveField( + model_name='menuitem', + name='all_day', + ), + ] diff --git a/v1/menu/models.py b/v1/menu/models.py index b0ea740..c180013 100644 --- a/v1/menu/models.py +++ b/v1/menu/models.py @@ -13,10 +13,9 @@ class MenuItem(models.Model): """ author = models.ForeignKey(User, on_delete=models.CASCADE, null=True) recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, related_name='menu_recipe') - all_day = models.BooleanField(default=False, blank=True) complete = models.BooleanField(default=False, blank=True) start_date = models.DateTimeField(null=True, blank=True) - end_date = models.DateTimeField(null=True, blank=True) + complete_date = models.DateTimeField(null=True, blank=True) class Meta: ordering = ['start_date', 'id'] diff --git a/v1/menu/serializers.py b/v1/menu/serializers.py index 106e582..52e8734 100644 --- a/v1/menu/serializers.py +++ b/v1/menu/serializers.py @@ -2,6 +2,8 @@ # encoding: utf-8 from rest_framework import serializers +import pytz +from datetime import datetime from v1.recipe.mixins import FieldLimiter from v1.recipe.serializers import MiniBrowseSerializer @@ -22,10 +24,19 @@ class Meta: 'author', 'complete', 'recipe', - 'all_day', 'start_date', - 'end_date', + 'complete_date', 'recipe', 'recipe_data', ] extra_kwargs = {'recipe': {'write_only': True}} + + def create(self, validated_data): + if validated_data.get('complete'): + validated_data['complete_date'] = datetime.now(pytz.utc) + return super(MenuItemSerializer, self).create(validated_data) + + def update(self, instance, validated_data): + if validated_data.get('complete') and not instance.complete: + validated_data['complete_date'] = datetime.now(pytz.utc) + return super(MenuItemSerializer, self).update(instance, validated_data) diff --git a/v1/menu/urls.py b/v1/menu/urls.py index c94d190..e81d1eb 100644 --- a/v1/menu/urls.py +++ b/v1/menu/urls.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # encoding: utf-8 -from django.conf.urls import url, include +from django.urls import include, path from rest_framework.routers import DefaultRouter from . import views @@ -11,5 +11,10 @@ router.register(r'menu-item', views.MenuItemViewSet) urlpatterns = [ - url('', include(router.urls)), + path('', include(router.urls)), + path( + 'menu-stats/', + views.MenuStatsViewSet.as_view(), + name='menu_stats' + ), ] diff --git a/v1/menu/views.py b/v1/menu/views.py index fe42b8b..93c164d 100644 --- a/v1/menu/views.py +++ b/v1/menu/views.py @@ -1,8 +1,13 @@ #!/usr/bin/env python # encoding: utf-8 -from rest_framework import viewsets +from rest_framework import viewsets, views +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from django.db.models import Count, Max +from django.core import serializers +from v1.recipe.models import Recipe from .models import MenuItem from .serializers import MenuItemSerializer from .permissions import IsMenuItemOwner @@ -16,10 +21,33 @@ class MenuItemViewSet(viewsets.ModelViewSet): queryset = MenuItem.objects.all() serializer_class = MenuItemSerializer permission_classes = (IsMenuItemOwner,) - filter_fields = ('recipe', 'start_date', 'end_date', 'complete') + filter_fields = ('recipe', 'start_date', 'complete_date', 'complete') def get_queryset(self): user = self.request.user if user and not user.is_anonymous: return MenuItem.objects.filter(author=user) - return MenuItem.objects.none() \ No newline at end of file + return MenuItem.objects.none() + + +class MenuStatsViewSet(views.APIView): + permission_classes = (IsAuthenticated,) + + def get(self, request): + return Response( + Recipe.objects.annotate( + num_menuitems=Count('menu_recipe'), + last_made=Max('menu_recipe__complete_date') + ).filter( + num_menuitems__gte=1, + menu_recipe__complete=True + ).values( + 'slug', + 'title', + 'num_menuitems', + 'last_made', + ).order_by( + '-last_made', + 'num_menuitems', + ) + )