Revert serializer/routes/view/model

This commit is contained in:
dormantman 2020-01-30 20:45:07 +03:00
parent bf941d8755
commit 14d9b32479
4 changed files with 150 additions and 153 deletions

View File

@ -14,26 +14,24 @@ from django.contrib.postgres.fields import ArrayField
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
from django.core.validators import MaxValueValidator, MinValueValidator, FileExtensionValidator
from django.db import models
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q, Prefetch
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 location.models import WineOriginAddressMixin
from main.models import Award, Currency
from phonenumber_field.modelfields import PhoneNumberField
from review.models import Review
from tag.models import Tag
from timetable.models import Timetable
from timezone_field import TimeZoneField
from utils.methods import transform_into_readable_str
from utils.models import (ProjectBaseMixin, TJSONField, URLImageMixin,
TranslatedFieldsMixin, BaseAttributes, GalleryMixin,
IntermediateGalleryModelMixin, HasTagsMixin,
FavoritesMixin, TypeDefaultImageMixin, FileMixin)
from utils.models import (
BaseAttributes, FavoritesMixin, GalleryMixin, HasTagsMixin, IntermediateGalleryModelMixin, ProjectBaseMixin,
TJSONField, TranslatedFieldsMixin, TypeDefaultImageMixin, URLImageMixin,
)
# todo: establishment type&subtypes check
@ -528,8 +526,8 @@ class EstablishmentQuerySet(models.QuerySet):
filters.update({
'id__in': models.Subquery(
UserRole.objects.filter(user=user, role__site__country__code=country_code)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
.distinct('user', 'establishment')
.values_list('establishment', flat=True)
)
})
return self.filter(**filters)
@ -1266,24 +1264,6 @@ 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(
@ -1309,57 +1289,25 @@ class MenuQuerySet(models.QuerySet):
"""Search by category."""
return self.filter(category__icontains=value)
def with_dishes(self):
return self.filter(~Q(dishes=None))
class Menu(TranslatedFieldsMixin, BaseAttributes):
class Menu(GalleryMixin, TranslatedFieldsMixin, BaseAttributes):
"""Menu model."""
name = models.CharField(_('name'), max_length=255, default='')
STR_FIELD_NAME = 'category'
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)
is_drinks_included = models.BooleanField(_('is drinks included'), default=False)
price = models.IntegerField(blank=True, null=True, default=None, verbose_name=_('price'))
schedule = models.ManyToManyField(
to='timetable.Timetable',
blank=True,
verbose_name=_('Menu schedule'),
verbose_name=_('Establishment schedule'),
related_name='menus',
)
uploads = models.ManyToManyField(
to='MenuFiles',
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"}')
# a la cartes
average_starter_price = models.FloatField(default=0, blank=True,
verbose_name=_('average starter price'))
average_main_dish_price = models.FloatField(default=0, blank=True,
verbose_name=_('average main dish price'))
renewal_per_year = models.IntegerField(null=True, blank=True,
verbose_name=_('renewal per year'))
average_desert_price = models.FloatField(default=0, blank=True,
verbose_name=_('average desert price'))
nb_wine = models.IntegerField(null=True, blank=True, verbose_name=_('NB wine'))
lowest_price = models.FloatField(null=True, blank=True, verbose_name=_('dish lowest price'))
highest_price = models.FloatField(null=True, blank=True, verbose_name=_('dish highest price'))
served_by_glasses = models.NullBooleanField(null=True,
verbose_name=_('is wine served by glass'))
price_min_by_glass = models.FloatField(null=True, blank=True,
verbose_name=_('min price for wine served by glass'))
price_max_by_glass = models.FloatField(null=True, blank=True,
verbose_name=_('max price for wine served by glass'))
old_id = models.PositiveIntegerField(_('old id'), blank=True, null=True, default=None)
objects = MenuQuerySet.as_manager()
@ -1370,15 +1318,43 @@ class Menu(TranslatedFieldsMixin, BaseAttributes):
ordering = ('-created',)
class MenuFiles(FileMixin, BaseAttributes):
"""Menu files"""
TYPES = (
('image', 'Image'),
('file', 'File')
class MenuGallery(IntermediateGalleryModelMixin):
menu = models.ForeignKey(
Menu,
null=True,
related_name='menu_gallery',
on_delete=models.CASCADE,
verbose_name=_('menu'),
)
image = models.ForeignKey(
'gallery.Image',
null=True,
related_name='menu_gallery',
on_delete=models.CASCADE,
verbose_name=_('image'),
)
name = models.CharField(_('name'), max_length=255, default='')
type = models.CharField(_('type'), choices=TYPES, max_length=65, default='')
class Meta:
"""Meta class."""
verbose_name = _('menu gallery')
verbose_name_plural = _('menu galleries')
unique_together = (('menu', 'is_main'), ('menu', 'image'))
class MenuUploads(BaseAttributes):
"""Menu files"""
menu = models.ForeignKey(
Menu,
verbose_name=_('menu'),
on_delete=models.CASCADE,
related_name='menu_uploads',
)
title = models.CharField(_('title'), max_length=255, default='')
file = models.FileField(
_('File'),
validators=[FileExtensionValidator(allowed_extensions=('doc', 'docx', 'pdf')), ],
)
class Meta:
verbose_name = _('menu upload')

View File

@ -1,18 +1,15 @@
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 django.db.models import F
from django.utils.translation import gettext_lazy as _
from establishment import models, serializers as model_serializers
from establishment.models import ContactEmail, ContactPhone, EstablishmentEmployee
from establishment.serializers import MenuDishSerializer
from gallery.models import Image
from location.serializers import AddressDetailSerializer, TranslatedField
from main.models import Currency
from main.serializers import AwardSerializer
from rest_framework import serializers
from utils.decorators import with_base_attributes
from utils.serializers import ImageBaseSerializer, ProjectModelSerializer, TimeZoneChoiceField
@ -593,59 +590,109 @@ 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"""
establishment_id = serializers.PrimaryKeyRelatedField(read_only=True)
establishment_slug = serializers.CharField(read_only=True, source='establishment.slug')
dishes = MenuDishSerializer(many=True, read_only=True)
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)
class Meta:
model = models.Menu
fields = [
'id',
'establishment_id',
'establishment_slug',
'dishes',
]
class MenuDishesCreateSerializer(ProjectModelSerializer):
"""Menu dishes create serializer"""
menu_id = serializers.IntegerField(write_only=True)
class Meta:
model = models.MenuDish
fields = [
'id',
'name',
'category',
'price',
'signature',
'menu_id'
'category_translated',
'establishment',
'is_drinks_included',
'schedule',
'plates',
'last_update',
'gallery',
]
def create(self, validated_data):
menu_id = validated_data.pop('menu_id')
menu = get_object_or_404(models.Menu, pk=menu_id)
instance = models.MenuDish.objects.create(**validated_data)
menu.dishes.add(instance)
return instance
class MenuDishesRUDSerializers(ProjectModelSerializer):
"""for dessert, main_course and starter category"""
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)
plates = _PlateSerializer(read_only=True, many=True, source='plate_set', allow_null=True)
gallery = ImageBaseSerializer(read_only=True, source='crop_gallery', many=True)
class Meta:
model = models.Menu
fields = [
'id',
'establishment_id',
'establishment_slug',
'dishes',
'category',
'plates',
'establishment',
'is_drinks_included',
'schedule',
'gallery',
]
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

@ -30,15 +30,13 @@ urlpatterns = [
name='note-rud'),
path('slug/<slug:slug>/admin/', views.EstablishmentAdminView.as_view(),
name='establishment-admin-list'),
path('menus/dishes/', views.MenuDishesListView.as_view(), name='menu-dishes-list'),
path('menus/dishes/create/', views.MenuDishesCreateView.as_view(), name='menu-dishes-create'),
path('menus/dishes/', views.MenuDishesListCreateView.as_view(), name='menu-dishes-list'),
path('menus/dishes/<int:pk>/', views.MenuDishesRUDView.as_view(), name='menu-dishes-rud'),
path('menus/dishes/slug/<slug:slug>/', 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'),
path('plates/<int:pk>/', views.PlateRUDView.as_view(), name='plate-rud'),
path('social_choice/', views.SocialChoiceListCreateView.as_view(), name='socials_choice'),

View File

@ -12,8 +12,7 @@ from establishment.models import EstablishmentEmployee
from timetable.models import Timetable
from timetable.serialziers import ScheduleCreateSerializer, ScheduleRUDSerializer
from utils.methods import get_permission_classes
from utils.permissions import (
IsEstablishmentManager, IsEstablishmentAdministrator, )
from utils.permissions import (IsEstablishmentAdministrator, IsEstablishmentManager)
from utils.views import CreateDestroyGalleryViewMixin
@ -160,23 +159,19 @@ class MenuListCreateView(generics.ListCreateAPIView):
"""Menu list create view."""
serializer_class = serializers.MenuSerializers
queryset = models.Menu.objects.all()
filter_backends = (DjangoFilterBackend,)
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator,
)
filter_backends = (DjangoFilterBackend,)
filterset_fields = (
'establishment__id',
'establishment',
'establishment__slug',
)
def get_queryset(self):
return super().get_queryset().prefetch_related('establishment')
class MenuRUDView(MenuRUDMixinViews, generics.RetrieveUpdateDestroyAPIView):
class MenuRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Menu RUD view."""
lookup_field = None
serializer_class = serializers.MenuRUDSerializers
queryset = models.Menu.objects.all()
permission_classes = get_permission_classes(
@ -185,26 +180,6 @@ class MenuRUDView(MenuRUDMixinViews, generics.RetrieveUpdateDestroyAPIView):
)
class MenuFilesListCreateView(generics.ListCreateAPIView):
"""Menu files list create view."""
serializer_class = serializers.MenuFilesSerializers
queryset = models.MenuFiles.objects.all()
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class MenuFilesRUDView(generics.RetrieveDestroyAPIView):
"""Menu files RUD view."""
serializer_class = serializers.MenuFilesSerializers
queryset = models.MenuFiles.objects.all()
permission_classes = get_permission_classes(
IsEstablishmentManager,
IsEstablishmentAdministrator
)
class SocialChoiceListCreateView(generics.ListCreateAPIView):
"""SocialChoice list create view."""
serializer_class = serializers.SocialChoiceSerializers
@ -614,6 +589,7 @@ class MenuDishesRUDView(MenuRUDMixinViews, generics.RetrieveUpdateDestroyAPIView
IsEstablishmentAdministrator
)
class MenuDishesCreateView(generics.CreateAPIView):
"""Menu (dessert, main_course, starter) list create view."""
serializer_class = serializers.MenuDishesCreateSerializer