Merge branch 'feature/gm-80' into develop

# Conflicts:
#	apps/establishment/serializers/back.py
This commit is contained in:
Anatoly 2019-09-19 14:32:10 +03:00
commit a09d6b28f1
13 changed files with 220 additions and 64 deletions

View File

@ -60,11 +60,6 @@ class EstablishmentAdmin(admin.ModelAdmin):
ReviewInline, CommentInline]
@admin.register(models.EstablishmentSchedule)
class EstablishmentSchedule(admin.ModelAdmin):
"""Establishment schedule"""
@admin.register(models.Position)
class PositionAdmin(admin.ModelAdmin):
"""Position admin."""

View File

@ -0,0 +1,16 @@
# Generated by Django 2.2.4 on 2019-09-18 12:07
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('establishment', '0020_merge_20190917_1415'),
]
operations = [
migrations.DeleteModel(
name='EstablishmentSchedule',
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 2.2.4 on 2019-09-18 14:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timetable', '0001_initial'),
('establishment', '0021_delete_establishmentschedule'),
]
operations = [
migrations.AddField(
model_name='establishment',
name='schedule',
field=models.ManyToManyField(related_name='schedule', to='timetable.Timetable', verbose_name='Establishment schedule'),
),
]

View File

@ -262,6 +262,13 @@ class Establishment(ProjectBaseMixin, ImageMixin, TranslatedFieldsMixin):
booking = models.URLField(blank=True, null=True, default=None,
verbose_name=_('Booking URL'))
is_publish = models.BooleanField(default=False, verbose_name=_('Publish status'))
schedule = models.ManyToManyField(to='timetable.Timetable',
verbose_name=_('Establishment schedule'),
related_name='schedule')
# holidays_from = models.DateTimeField(verbose_name=_('Holidays from'),
# help_text=_('Holidays closing date from'))
# holidays_to = models.DateTimeField(verbose_name=_('Holidays to'),
# help_text=_('Holidays closing date to'))
awards = generic.GenericRelation(to='main.Award')
tags = generic.GenericRelation(to='main.MetaDataContent')
reviews = generic.GenericRelation(to='review.Review')
@ -394,23 +401,6 @@ class EstablishmentScheduleQuerySet(models.QuerySet):
"""QuerySet for model EstablishmentSchedule"""
class EstablishmentSchedule(BaseAttributes):
"""Establishment schedule model."""
establishment = models.OneToOneField(Establishment,
related_name='schedule',
on_delete=models.CASCADE,
verbose_name=_('Establishment'))
schedule = models.ManyToManyField(to='timetable.Timetable',
verbose_name=_('Establishment schedule'))
objects = EstablishmentScheduleQuerySet.as_manager()
class Meta:
"""Meta class"""
verbose_name = _('Establishment schedule')
verbose_name_plural = _('Establishment schedules')
class ContactPhone(models.Model):
"""Contact phone model."""
establishment = models.ForeignKey(

View File

@ -1,9 +1,12 @@
import json
from rest_framework import serializers
from establishment import models
from timetable.models import Timetable
from establishment.serializers import (
EstablishmentBaseSerializer, PlateSerializer, ContactEmailsSerializer,
ContactPhonesSerializer, SocialNetworkRelatedSerializers)
ContactPhonesSerializer, SocialNetworkRelatedSerializers, EstablishmentDetailSerializer
)
from main.models import Currency

View File

@ -9,7 +9,7 @@ from location.serializers import AddressSerializer
from main.models import MetaDataContent
from main.serializers import MetaDataContentSerializer, AwardSerializer, CurrencySerializer
from review import models as review_models
from timetable.models import Timetable
from timetable.serialziers import ScheduleRUDSerializer
from utils import exceptions as utils_exceptions
@ -111,22 +111,6 @@ class EstablishmentSubTypeSerializer(serializers.ModelSerializer):
fields = ('id', 'name_translated')
class EstablishmentScheduleSerializer(serializers.ModelSerializer):
"""Serializer for Establishment model."""
weekday = serializers.CharField(source='get_weekday_display')
class Meta:
"""Meta class."""
model = Timetable
fields = (
'weekday',
'lunch_start',
'lunch_end',
'dinner_start',
'dinner_end',
)
class ReviewSerializer(serializers.ModelSerializer):
"""Serializer for model Review."""
text_translated = serializers.CharField(read_only=True)
@ -204,9 +188,7 @@ class EstablishmentDetailSerializer(EstablishmentListSerializer):
"""Serializer for Establishment model."""
description_translated = serializers.CharField(allow_null=True)
awards = AwardSerializer(many=True)
schedule = EstablishmentScheduleSerializer(source='schedule.schedule',
many=True,
allow_null=True)
schedule = ScheduleRUDSerializer(many=True, allow_null=True)
phones = ContactPhonesSerializer(read_only=True, many=True, )
emails = ContactEmailsSerializer(read_only=True, many=True, )
review = serializers.SerializerMethodField()

View File

@ -10,6 +10,10 @@ app_name = 'establishment'
urlpatterns = [
path('', views.EstablishmentListCreateView.as_view(), name='list'),
path('<int:pk>/', views.EstablishmentRetrieveView.as_view(), name='detail'),
path('<int:pk>/schedule/<int:schedule_id>/', views.EstablishmentScheduleRUDView.as_view(),
name='schedule-rud'),
path('<int:pk>/schedule/', views.EstablishmentScheduleCreateView.as_view(),
name='schedule-create'),
path('menus/', views.MenuListCreateView.as_view(), name='menu-list'),
path('menus/<int:pk>/', views.MenuRUDView.as_view(), name='menu-rud'),
path('plates/', views.PlateListCreateView.as_view(), name='plates'),

View File

@ -2,7 +2,8 @@
from rest_framework import generics
from establishment import models, serializers
from establishment import models
from establishment import serializers
from establishment.views.common import EstablishmentMixin

View File

@ -7,8 +7,9 @@ from comment import models as comment_models
from establishment import filters
from establishment import models, serializers
from main.models import MetaDataContent
from utils.views import JWTGenericViewMixin
from establishment.views import EstablishmentMixin
from timetable.serialziers import ScheduleRUDSerializer, ScheduleCreateSerializer
from timetable.models import Timetable
class EstablishmentListView(EstablishmentMixin, generics.ListAPIView):
@ -34,12 +35,12 @@ class EstablishmentSimilarListView(EstablishmentListView):
.order_by('-total_mark')[:13]
class EstablishmentRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.RetrieveAPIView):
class EstablishmentRetrieveView(EstablishmentMixin, generics.RetrieveAPIView):
"""Resource for getting a establishment."""
serializer_class = serializers.EstablishmentDetailSerializer
class EstablishmentTypeListView(JWTGenericViewMixin, generics.ListAPIView):
class EstablishmentTypeListView(generics.ListAPIView):
"""Resource for getting a list of establishment types."""
permission_classes = (permissions.AllowAny,)
@ -122,7 +123,7 @@ class EstablishmentFavoritesCreateDestroyView(generics.CreateAPIView, generics.D
return obj
class EstablishmentNearestRetrieveView(EstablishmentMixin, JWTGenericViewMixin, generics.ListAPIView):
class EstablishmentNearestRetrieveView(EstablishmentMixin, generics.ListAPIView):
"""Resource for getting list of nearest establishments."""
serializer_class = serializers.EstablishmentListSerializer
filter_class = filters.EstablishmentFilter
@ -151,3 +152,40 @@ class EstablishmentTagListView(generics.ListAPIView):
"""Override get_queryset method"""
return MetaDataContent.objects.by_content_type(app_label='establishment',
model='establishment')
class EstablishmentScheduleRUDView(generics.RetrieveUpdateDestroyAPIView):
"""Establishment schedule RUD view"""
serializer_class = ScheduleRUDSerializer
def get_object(self):
"""
Returns the object the view is displaying.
"""
lookup_url_kwargs = ('pk', 'schedule_id')
assert lookup_url_kwargs not in self.kwargs.keys(), (
'Expected view %s to be called with a URL keyword argument '
'named "%s". Fix your URL conf, or set the `.lookup_field` '
'attribute on the view correctly.' %
(self.__class__.__name__, lookup_url_kwargs)
)
establishment_pk = self.kwargs['pk']
schedule_id = self.kwargs['schedule_id']
establishment = get_object_or_404(klass=models.Establishment.objects.all(),
pk=establishment_pk)
schedule = get_object_or_404(klass=establishment.schedule,
id=schedule_id)
# May raise a permission denied
self.check_object_permissions(self.request, establishment)
self.check_object_permissions(self.request, schedule)
return schedule
class EstablishmentScheduleCreateView(generics.CreateAPIView):
"""Establishment schedule Create view"""
serializer_class = ScheduleCreateSerializer

View File

@ -334,11 +334,10 @@ class Carousel(models.Model):
@property
def image(self):
# Check if Generic obj has an image
if not hasattr(self.content_object.image, 'url'):
# Check if Generic obj has a FK to gallery
if hasattr(self.content_object.image, 'url'):
return self.content_object.image
if hasattr(self.content_object.image.image, 'url'):
return self.content_object.image.image
return self.content_object.image
@property
def model_name(self):

View File

@ -0,0 +1,43 @@
# Generated by Django 2.2.4 on 2019-09-19 11:24
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('timetable', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='timetable',
name='closed_at',
field=models.TimeField(null=True, verbose_name='Closed time'),
),
migrations.AddField(
model_name='timetable',
name='opening_at',
field=models.TimeField(null=True, verbose_name='Opening time'),
),
migrations.AlterField(
model_name='timetable',
name='dinner_end',
field=models.TimeField(null=True, verbose_name='Dinner end time'),
),
migrations.AlterField(
model_name='timetable',
name='dinner_start',
field=models.TimeField(null=True, verbose_name='Dinner start time'),
),
migrations.AlterField(
model_name='timetable',
name='lunch_end',
field=models.TimeField(null=True, verbose_name='Lunch end time'),
),
migrations.AlterField(
model_name='timetable',
name='lunch_start',
field=models.TimeField(null=True, verbose_name='Lunch start time'),
),
]

View File

@ -23,10 +23,13 @@ class Timetable(ProjectBaseMixin):
(SUNDAY, _('Sunday')))
weekday = models.PositiveSmallIntegerField(choices=WEEKDAYS_CHOICES, verbose_name=_('Week day'))
lunch_start = models.TimeField(verbose_name=_('Lunch start time'))
lunch_end = models.TimeField(verbose_name=_('Lunch end time'))
dinner_start = models.TimeField(verbose_name=_('Dinner start time'))
dinner_end = models.TimeField(verbose_name=_('Dinner end time'))
lunch_start = models.TimeField(verbose_name=_('Lunch start time'), null=True)
lunch_end = models.TimeField(verbose_name=_('Lunch end time'), null=True)
dinner_start = models.TimeField(verbose_name=_('Dinner start time'), null=True)
dinner_end = models.TimeField(verbose_name=_('Dinner end time'), null=True)
opening_at = models.TimeField(verbose_name=_('Opening time'), null=True)
closed_at = models.TimeField(verbose_name=_('Closed time'), null=True)
class Meta:
"""Meta class."""

View File

@ -1,16 +1,79 @@
"""Serializer for app timetable"""
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from timetable import models
from establishment.models import Establishment
from timetable.models import Timetable
class TimetableSerializer(serializers.ModelSerializer):
"""Serializer for model Timetable"""
class ScheduleRUDSerializer(serializers.ModelSerializer):
"""Serializer for Establishment model."""
weekday_display = serializers.CharField(source='get_weekday_display',
read_only=True)
lunch_start = serializers.TimeField(required=False)
lunch_end = serializers.TimeField(required=False)
dinner_start = serializers.TimeField(required=False)
dinner_end = serializers.TimeField(required=False)
opening_at = serializers.TimeField(required=False)
closed_at = serializers.TimeField(required=False)
NULLABLE_FIELDS = ['lunch_start', 'lunch_end', 'dinner_start',
'dinner_end', 'opening_at', 'closed_at']
class Meta:
"""Meta class."""
model = models.Timetable
fields = (
model = Timetable
fields = [
'id',
'weekday_display',
'lunch_start',
'lunch_end',
'dinner_start',
'dinner_end',
'opening_at',
'closed_at',
]
def validate(self, attrs):
"""Override validate method"""
establishment_pk = self.context.get('request')\
.parser_context.get('view')\
.kwargs.get('pk')
# Check if establishment exists.
establishment_qs = Establishment.objects.filter(pk=establishment_pk)
if not establishment_qs.exists():
raise serializers.ValidationError({'detail': _('Establishment not found.')})
attrs['establishment'] = establishment_qs.first()
# If fields not in request data then put it in attrs with None value.
if not self.partial:
for field in self.NULLABLE_FIELDS:
if field not in attrs:
attrs.setdefault(field, None)
return attrs
class ScheduleCreateSerializer(ScheduleRUDSerializer):
"""Serializer for Establishment model."""
weekday = serializers.IntegerField(write_only=True)
class Meta:
"""Meta class."""
model = Timetable
fields = ScheduleRUDSerializer.Meta.fields + [
'weekday',
'start',
'end',
)
]
def create(self, validated_data):
"""Override create method"""
establishment = validated_data.pop('establishment')
weekday = validated_data.get('weekday')
instance = super().create(validated_data)
schedule_qs = establishment.schedule.filter(weekday=weekday)
if schedule_qs.exists():
schedule_qs.delete()
establishment.schedule.add(instance)
return instance