From 1b001f303abdd3afa191836daa5a700ba151ef3f Mon Sep 17 00:00:00 2001 From: evgeniy-st Date: Sun, 1 Sep 2019 14:17:03 +0300 Subject: [PATCH] extended establishment api enpoint by attribute of 'employees' --- apps/establishment/admin.py | 5 +++ apps/establishment/models.py | 71 ++++++++++++++++++++++++++++++- apps/establishment/serializers.py | 17 ++++++++ apps/establishment/views.py | 5 ++- 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/apps/establishment/admin.py b/apps/establishment/admin.py index d40950b1..9c02459e 100644 --- a/apps/establishment/admin.py +++ b/apps/establishment/admin.py @@ -34,3 +34,8 @@ class EstablishmentAdmin(admin.ModelAdmin): @admin.register(models.EstablishmentSchedule) class EstablishmentSchedule(admin.ModelAdmin): """Establishment schedule""" + + +@admin.register(models.Position) +class PositionAdmin(admin.ModelAdmin): + """Position admin.""" diff --git a/apps/establishment/models.py b/apps/establishment/models.py index 68b8872e..340b96bb 100644 --- a/apps/establishment/models.py +++ b/apps/establishment/models.py @@ -1,12 +1,13 @@ """Establishment models.""" from functools import reduce +from django.contrib.contenttypes import fields as generic from django.core.exceptions import ValidationError from django.db import models +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from location.models import Address from utils.models import (ProjectBaseMixin, ImageMixin, TJSONField, TraslatedFieldsMixin, BaseAttributes) -from django.contrib.contenttypes import fields as generic # todo: establishment type&subtypes check @@ -70,6 +71,14 @@ class EstablishmentQuerySet(models.QuerySet): else: return self.none() + def prefetch_actual_employees(self): + """Prefetch actual employees.""" + return self.prefetch_related( + models.Prefetch('establishmentemployee_set', + queryset=EstablishmentEmployee.objects.actual().select_related( + 'position'), + to_attr='actual_establishment_employees')) + class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin): """Establishment model.""" @@ -123,6 +132,7 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin): country = self.address.city.country return country.low_price, country.high_price + # todo: make via prefetch @property def subtypes(self): return EstablishmentSubType.objects.filter( @@ -141,6 +151,65 @@ class Establishment(ProjectBaseMixin, ImageMixin, TraslatedFieldsMixin): self.establishment_subtypes.add(establishment_subtype) +class Position(BaseAttributes, TraslatedFieldsMixin): + """Position model.""" + + name = TJSONField(blank=True, null=True, default=None, verbose_name=_('Description'), + help_text='{"en":"some text"}') + + class Meta: + """Meta class.""" + + verbose_name = _('Position') + verbose_name_plural = _('Positions') + + +class EstablishmentEmployeeQuerySet(models.QuerySet): + """Extended queryset for EstablishmEntemployee model.""" + + def actual(self): + """Actual objects..""" + now = timezone.now() + return self.filter(models.Q(from_date__lte=now), + (models.Q(to_date__gte=now) | + models.Q(to_date__isnull=True))) + + +class EstablishmentEmployee(BaseAttributes): + """EstablishmentEmployee model.""" + + establishment = models.ForeignKey(Establishment, on_delete=models.PROTECT, + verbose_name=_('Establishment')) + employee = models.ForeignKey('establishment.Employee', on_delete=models.PROTECT, + verbose_name=_('Employee')) + from_date = models.DateTimeField(default=timezone.now, verbose_name=_('From date')) + to_date = models.DateTimeField(blank=True, null=True, default=None, + verbose_name=_('To date')) + position = models.ForeignKey(Position, on_delete=models.PROTECT, + verbose_name=_('Position')) + + objects = EstablishmentEmployeeQuerySet.as_manager() + + +class Employee(BaseAttributes): + """Employee model.""" + + user = models.OneToOneField('account.User', on_delete=models.PROTECT, + null=True, blank=True, default=None, + verbose_name=_('User')) + name = models.CharField(max_length=255, verbose_name=_('Last name')) + establishments = models.ManyToManyField(Establishment, related_name='employees', + through=EstablishmentEmployee) + awards = generic.GenericRelation(to='main.Award') + tags = generic.GenericRelation(to='main.MetaDataContent') + + class Meta: + """Meta class.""" + + verbose_name = _('Employee') + verbose_name_plural = _('Employees') + + class EstablishmentScheduleQuerySet(models.QuerySet): """QuerySet for model EstablishmentSchedule""" diff --git a/apps/establishment/serializers.py b/apps/establishment/serializers.py index 49788db3..4da3f139 100644 --- a/apps/establishment/serializers.py +++ b/apps/establishment/serializers.py @@ -46,6 +46,20 @@ class EstablishmentScheduleSerializer(serializers.ModelSerializer): ) +class EstablishmentEmployeeSerializer(serializers.ModelSerializer): + """Serializer for actual employees.""" + + id = serializers.IntegerField(source='employee.id') + name = serializers.CharField(source='employee.name') + position_translated = serializers.CharField(source='position.name_translated') + + class Meta: + """Meta class.""" + + model = models.Employee + fields = ('id', 'name', 'position_translated') + + class EstablishmentSerializer(serializers.ModelSerializer): """Serializer for Establishment model.""" @@ -59,6 +73,8 @@ class EstablishmentSerializer(serializers.ModelSerializer): schedule = EstablishmentScheduleSerializer(source='schedule.schedule', many=True, allow_null=True) + employees = EstablishmentEmployeeSerializer(source='actual_establishment_employees', + many=True) class Meta: """Meta class.""" @@ -79,4 +95,5 @@ class EstablishmentSerializer(serializers.ModelSerializer): 'tags', 'awards', 'schedule', + 'employees', ) diff --git a/apps/establishment/views.py b/apps/establishment/views.py index 459aeeac..525118e2 100644 --- a/apps/establishment/views.py +++ b/apps/establishment/views.py @@ -10,9 +10,12 @@ class EstablishmentListView(JWTGenericViewMixin, generics.ListAPIView): permission_classes = (permissions.AllowAny,) serializer_class = serializers.EstablishmentSerializer - queryset = models.Establishment.objects.all() filter_class = filters.EstablishmentFilter + def get_queryset(self): + """Overrided method 'get_queryset'.""" + return models.Establishment.objects.all().prefetch_actual_employees() + class EstablishmentRetrieveView(JWTGenericViewMixin, generics.RetrieveAPIView): """Resource for getting a establishment."""