Added menu dishes

This commit is contained in:
dormantman 2020-01-29 16:11:53 +03:00
parent bcc5f2da51
commit a6db15ed50
5 changed files with 74 additions and 168 deletions

View File

@ -6,36 +6,32 @@ from typing import List
import elasticsearch_dsl
from django.conf import settings
from django.shortcuts import get_object_or_404
from django.contrib.contenttypes import fields as generic
from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import Point
from django.contrib.gis.measure import Distance as DistanceMeasure
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.search import TrigramDistance, TrigramSimilarity
from django.contrib.postgres.indexes import GinIndex
from django.contrib.postgres.search import TrigramSimilarity
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator, FileExtensionValidator
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch, Sum
from django.db.models import Case, ExpressionWrapper, F, Prefetch, Q, Subquery, When
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from phonenumber_field.modelfields import PhoneNumberField
from timezone_field import TimeZoneField
from location.models import Address
from timetable.models import Timetable
from location.models import WineOriginAddressMixin
from main.models import Award, Currency
from review.models import Review
from tag.models import Tag
from timetable.models import Timetable
from utils.methods import transform_into_readable_str
from utils.models import (
ProjectBaseMixin, TJSONField, URLImageMixin,
TranslatedFieldsMixin, BaseAttributes, GalleryMixin,
IntermediateGalleryModelMixin, HasTagsMixin,
FavoritesMixin, TypeDefaultImageMixin, FileMixin,
ImageMixin,
BaseAttributes, FavoritesMixin, FileMixin, GalleryMixin, HasTagsMixin, IntermediateGalleryModelMixin,
ProjectBaseMixin, TJSONField, TranslatedFieldsMixin, TypeDefaultImageMixin, URLImageMixin,
)
@ -564,8 +560,8 @@ class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin,
verbose_name=_('Facebook URL'))
twitter = models.URLField(blank=True, null=True, default=None, max_length=255,
verbose_name=_('Twitter URL'))
instagram =models.URLField(blank=True, null=True, default=None, max_length=255,
verbose_name=_('Instagram URL'))
instagram = models.URLField(blank=True, null=True, default=None, max_length=255,
verbose_name=_('Instagram URL'))
lafourchette = models.URLField(blank=True, null=True, default=None, max_length=255,
verbose_name=_('Lafourchette URL'))
guestonline_id = models.PositiveIntegerField(blank=True, verbose_name=_('guestonline id'),
@ -737,7 +733,8 @@ class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin,
now_at_est_tz = datetime.now(tz=self.tz)
current_week = now_at_est_tz.weekday()
schedule_for_today = self.schedule.filter(weekday=current_week).first()
if schedule_for_today is None or schedule_for_today.opening_time is None or schedule_for_today.ending_time is None:
if schedule_for_today is None or schedule_for_today.opening_time is None or schedule_for_today.ending_time is\
None:
return False
time_at_est_tz = now_at_est_tz.time()
return schedule_for_today.ending_time > time_at_est_tz > schedule_for_today.opening_time
@ -749,8 +746,10 @@ class Establishment(GalleryMixin, ProjectBaseMixin, URLImageMixin,
@property
def tags_indexing(self):
return [{'id': tag.metadata.id,
'label': tag.metadata.label} for tag in self.tags.all()]
return [{
'id': tag.metadata.id,
'label': tag.metadata.label
} for tag in self.tags.all()]
@property
def last_published_review(self):
@ -1244,6 +1243,24 @@ class Plate(TranslatedFieldsMixin, models.Model):
verbose_name_plural = _('plates')
class MenuDish(BaseAttributes):
"""Dish model."""
STR_FIELD_NAME = 'category'
name = models.CharField(_('name'), max_length=255, default='')
category = TJSONField(
blank=True, null=True, default=None, verbose_name=_('category'),
help_text='{"en-GB":"some text"}')
price = models.IntegerField(blank=True, null=True, default=None, verbose_name=_('price'))
signature = models.BooleanField(_('signature'), default=False)
class Meta:
verbose_name = _('dish')
verbose_name_plural = _('dishes')
ordering = ('-created',)
class MenuQuerySet(models.QuerySet):
def with_schedule_plates_establishment(self):
return self.select_related(
@ -1270,15 +1287,10 @@ class MenuQuerySet(models.QuerySet):
return self.filter(category__icontains=value)
class Menu(GalleryMixin, TranslatedFieldsMixin, BaseAttributes):
class Menu(TranslatedFieldsMixin, BaseAttributes):
"""Menu model."""
STR_FIELD_NAME = 'category'
name = models.CharField(_('name'), max_length=255, default='')
category = TJSONField(
blank=True, null=True, default=None, verbose_name=_('category'),
help_text='{"en-GB":"some text"}')
establishment = models.ForeignKey(
'establishment.Establishment', verbose_name=_('establishment'),
on_delete=models.CASCADE)
@ -1294,6 +1306,14 @@ class Menu(GalleryMixin, TranslatedFieldsMixin, BaseAttributes):
blank=True,
verbose_name=_('Menu files'),
)
dishes = models.ManyToManyField(
to='MenuDish',
blank=True,
verbose_name=_('Menu dishes')
)
category = TJSONField(
blank=True, null=True, default=None, verbose_name=_('category'),
help_text='{"en-GB":"some text"}')
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)

View File

@ -1,12 +1,14 @@
from functools import lru_cache
from django.db.models import F
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from account.serializers.common import UserShortSerializer
from establishment import models, serializers as model_serializers
from establishment.models import ContactPhone, EstablishmentEmployee, ContactEmail
from establishment.serializers import MenuDishSerializer
from gallery.models import Image
from location.models import Address
from location.serializers import AddressDetailSerializer, TranslatedField
@ -580,109 +582,36 @@ class EstablishmentEmployeePositionsSerializer(serializers.ModelSerializer):
]
class _PlateSerializer(ProjectModelSerializer):
name_translated = TranslatedField()
class Meta:
model = models.Plate
fields = [
'name_translated',
'price',
]
class _MenuUploadsSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField()
original_url = serializers.URLField()
class MenuDishesSerializer(ProjectModelSerializer):
"""for dessert, main_course and starter category"""
plates = _PlateSerializer(read_only=True, many=True, source='plate_set', allow_null=True)
category_translated = serializers.CharField(read_only=True)
last_update = serializers.DateTimeField(source='created')
gallery = ImageBaseSerializer(read_only=True, source='crop_gallery', many=True)
establishment_id = serializers.PrimaryKeyRelatedField(read_only=True)
establishment_slug = serializers.CharField(read_only=True, source='establishment.slug')
dishes = MenuDishSerializer(many=True, read_only=True)
class Meta:
model = models.Menu
fields = [
'id',
'category',
'category_translated',
'establishment',
'is_drinks_included',
'schedule',
'plates',
'last_update',
'gallery',
'establishment_id',
'establishment_slug',
'dishes',
]
class MenuDishesRUDSerializers(ProjectModelSerializer):
"""for dessert, main_course and starter category"""
plates = _PlateSerializer(read_only=True, many=True, source='plate_set', allow_null=True)
gallery = ImageBaseSerializer(read_only=True, source='crop_gallery', many=True)
establishment_id = serializers.PrimaryKeyRelatedField(queryset=models.Establishment.objects.all())
establishment_slug = serializers.CharField(read_only=True, source='establishment.slug')
dishes = MenuDishSerializer(many=True, read_only=True)
class Meta:
model = models.Menu
fields = [
'id',
'category',
'plates',
'establishment',
'is_drinks_included',
'schedule',
'gallery',
'establishment_id',
'establishment_slug',
'dishes',
]
# class MenuGallerySerializer(serializers.ModelSerializer):
# """Serializer class for model MenuGallery."""
#
# class Meta:
# """Meta class"""
#
# model = models.MenuGallery
# fields = [
# 'id',
# 'is_main',
# ]
#
# @property
# def request_kwargs(self):
# """Get url kwargs from request."""
# return self.context.get('request').parser_context.get('kwargs')
#
# def create(self, validated_data):
# menu_pk = self.request_kwargs.get('pk')
# image_id = self.request_kwargs.get('image_id')
# qs = models.MenuGallery.objects.filter(image_id=image_id, menu_id=menu_pk)
# instance = qs.first()
# if instance:
# qs.update(**validated_data)
# return instance
# return super().create(validated_data)
#
# def validate(self, attrs):
# """Override validate method."""
# menu_pk = self.request_kwargs.get('pk')
# image_id = self.request_kwargs.get('image_id')
#
# menu_qs = models.Menu.objects.filter(pk=menu_pk)
# image_qs = Image.objects.filter(id=image_id)
#
# if not menu_qs.exists():
# raise serializers.ValidationError({'detail': _('Menu not found')})
# if not image_qs.exists():
# raise serializers.ValidationError({'detail': _('Image not found')})
#
# menu = menu_qs.first()
# image = image_qs.first()
#
# attrs['menu'] = menu
# attrs['image'] = image
#
# return attrs

View File

@ -72,6 +72,19 @@ class PlateSerializer(ProjectModelSerializer):
]
class MenuDishSerializer(ProjectModelSerializer):
class Meta:
model = models.MenuDish
fields = [
'id',
'name',
'category',
'category_translated',
'price',
'signature'
]
class MenuFilesSerializers(ProjectModelSerializer):
menu_id = serializers.IntegerField(write_only=True)
@ -113,7 +126,6 @@ class MenuSerializers(ProjectModelSerializer):
'drinks_included',
'schedules',
'uploads',
'category',
]
def create(self, validated_data):
@ -142,7 +154,6 @@ class MenuRUDSerializers(ProjectModelSerializer):
'drinks_included',
'schedules',
'uploads',
'category',
]

View File

@ -30,13 +30,11 @@ urlpatterns = [
name='note-rud'),
path('slug/<slug:slug>/admin/', views.EstablishmentAdminView.as_view(),
name='establishment-admin-list'),
path('menus/dishes/', views.MenuDishesListCreateView.as_view(), name='menu-dishes-list'),
path('menus/dishes/', views.MenuDishesListView.as_view(), name='menu-dishes-list'),
path('menus/dishes/<int:pk>/', views.MenuDishesRUDView.as_view(), name='menu-dishes-rud'),
# path('menus/dishes/<int:pk>/gallery/', views.MenuGalleryListView.as_view(), name='menu-dishes-gallery-list'),
# path('menus/dishes/<int:pk>/gallery/<int:image_id>/', views.MenuGalleryCreateDestroyView.as_view(),
# name='menu-dishes-gallery-create-destroy'),
path('menus/', views.MenuListCreateView.as_view(), name='menu-list'),
path('menus/<int:pk>/', views.MenuRUDView.as_view(), name='menu-rud'),
path('menus/slug/<slug:slug>/', views.MenuRUDView.as_view(), name='menu-rud'),
path('menus/uploads/', views.MenuFilesListCreateView.as_view(), name='menu-files-list'),
path('menus/uploads/<int:pk>/', views.MenuFilesRUDView.as_view(), name='menu-files-rud'),
path('plates/', views.PlateListCreateView.as_view(), name='plates'),

View File

@ -466,10 +466,10 @@ class EstablishmentAdminView(generics.ListAPIView):
return User.objects.establishment_admin(establishment).distinct()
class MenuDishesListCreateView(generics.ListCreateAPIView):
class MenuDishesListView(generics.ListAPIView):
"""Menu (dessert, main_course, starter) list create view."""
serializer_class = serializers.MenuDishesSerializer
queryset = models.Menu.objects.with_schedule_plates_establishment().dishes().distinct()
queryset = models.Menu.objects.all()
permission_classes = [IsWineryReviewer | IsEstablishmentManager]
filter_class = filters.MenuDishesBackFilter
@ -477,57 +477,5 @@ class MenuDishesListCreateView(generics.ListCreateAPIView):
class MenuDishesRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Menu (dessert, main_course, starter) RUD view."""
serializer_class = serializers.MenuDishesRUDSerializers
queryset = models.Menu.objects.dishes().distinct()
queryset = models.Menu.objects.all()
permission_classes = [IsWineryReviewer | IsEstablishmentManager]
# class MenuGalleryListView(generics.ListAPIView):
# """Resource for returning gallery for menu for back-office users."""
# serializer_class = serializers.ImageBaseSerializer
# permission_classes = [IsWineryReviewer | IsEstablishmentManager]
# queryset = models.Menu.objects.with_schedule_plates_establishment().with_gallery().dishes()
#
# def get_object(self):
# """Override get_object method."""
# qs = super(MenuGalleryListView, self).get_queryset()
# menu = get_object_or_404(qs, pk=self.kwargs.get('pk'))
#
# # May raise a permission denied
# # self.check_object_permissions(self.request, menu)
#
# return menu
#
# def get_queryset(self):
# """Override get_queryset method."""
# return self.get_object().crop_gallery
#
#
# class MenuGalleryCreateDestroyView(CreateDestroyGalleryViewMixin):
# """Resource for a create gallery for menu for back-office users."""
# serializer_class = serializers.MenuGallerySerializer
# permission_classes = [IsWineryReviewer | IsEstablishmentManager]
#
# def get_queryset(self):
# """Override get_queryset method."""
# qs = models.Menu.objects.with_schedule_plates_establishment().with_gallery().dishes()
# return qs
#
# def create(self, request, *args, **kwargs):
# _ = super().create(request, *args, **kwargs)
# news_qs = self.filter_queryset(self.get_queryset())
# return response.Response(
# data=serializers.MenuDishesRUDSerializers(get_object_or_404(news_qs, pk=kwargs.get('pk'))).data
# )
#
# def get_object(self):
# """
# Returns the object the view is displaying.
# """
# menu_qs = self.filter_queryset(self.get_queryset())
#
# menu = get_object_or_404(menu_qs, pk=self.kwargs.get('pk'))
# gallery = get_object_or_404(menu.menu_gallery, image_id=self.kwargs.get('image_id'))
#
# # May raise a permission denied
# self.check_object_permissions(self.request, gallery)
#
# return gallery