Skip to content

Commit

Permalink
Merge pull request #219 from ZUS666/develop
Browse files Browse the repository at this point in the history
update
  • Loading branch information
Arseny13 authored Oct 23, 2023
2 parents ee86292 + 39a0460 commit 0188a49
Show file tree
Hide file tree
Showing 15 changed files with 1,185 additions and 245 deletions.
14 changes: 3 additions & 11 deletions api_spot/api/serializers/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ class LocationGetSerializer(serializers.ModelSerializer):
read_only=True,
source='location_extra_photo'
)
is_favorited = serializers.SerializerMethodField()
low_price = serializers.DecimalField(max_digits=10, decimal_places=2)
rating = serializers.DecimalField(max_digits=3, decimal_places=2)
is_favorited = serializers.BooleanField(default=False)
coordinates = serializers.SerializerMethodField()

class Meta:
Expand All @@ -35,7 +37,6 @@ class Meta:
'main_photo',
'extra_photo',
'rating',
'low_price',
'short_annotation',
'description',
'is_favorited',
Expand All @@ -45,15 +46,6 @@ class Meta:
'days_open'
)

def get_is_favorited(self, instance, *args, **kwargs) -> bool:
"""
Отображение наличия location в избранном при листинге location.
"""
user = self.context['request'].user
if not user.is_authenticated:
return False
return instance.favorites.filter(user_id=user.id).exists()

def get_coordinates(self, instance) -> list[Decimal]:
"""
Список координат
Expand Down
15 changes: 0 additions & 15 deletions api_spot/api/tasks.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,8 @@
from celery import shared_task
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.shortcuts import get_object_or_404
from django.template.loader import render_to_string

from spots.constants import NOT_PAID, PAID
from spots.models.order import Order


@shared_task()
def change_status_task(order_id: int) -> str:
"""Таска изменения статуса после n секнуд."""
order = get_object_or_404(Order, pk=order_id)
if order.status != PAID:
order.status = NOT_PAID
order.save()
return f'Cтатус у {order_id} изменен'
return f'Cтатус у {order_id} не изменен'


@shared_task()
def send_mail_task(user_email, subject, template, add_dict=None):
Expand Down
38 changes: 36 additions & 2 deletions api_spot/api/views/locations.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.db.models import Avg, Count, Min, Prefetch
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
from rest_framework import filters
Expand All @@ -18,14 +19,29 @@ class LocationViewSet(RetrieveListViewSet):
Представление подробной информации о локациях с возможностью фильтрации
по названию, категориям, метро и избранному.
"""
queryset = Location.objects.all().prefetch_related('location_extra_photo')
queryset = Location.objects.all().prefetch_related(
Prefetch('location_extra_photo')
)
serializer_class = LocationGetSerializer
permission_classes = (AllowAny,)
pagination_class = LimitOffsetPagination
filter_backends = (DjangoFilterBackend, filters.SearchFilter,)
filterset_class = LocationFilter
search_fields = ('$name', )

def get_queryset(self):
user = self.request.user
if user.is_authenticated:
return super().get_queryset().annotate(
is_favorited=Count('favorites', favorites__user=user),
low_price=Min('spots__price__total_price'),
rating=Avg('spots__orders__reviews__rating'),
)
return super().get_queryset().annotate(
low_price=Min('spots__price__total_price'),
rating=Avg('spots__orders__reviews__rating'),
)


@extend_schema(
tags=('locations',)
Expand All @@ -43,6 +59,19 @@ class LocationShortListAPIView(ListAPIView):
filterset_class = LocationFilter
search_fields = ('$name', )

def get_queryset(self):
user = self.request.user
if user.is_authenticated:
return super().get_queryset().annotate(
is_favorited=Count('favorites', favorites__user=user),
low_price=Min('spots__price__total_price'),
rating=Avg('spots__orders__reviews__rating')
)
return super().get_queryset().annotate(
low_price=Min('spots__price__total_price'),
rating=Avg('spots__orders__reviews__rating'),
)


@extend_schema(
tags=('locations',)
Expand All @@ -51,9 +80,14 @@ class LocationMapListAPIView(ListAPIView):
"""
Представление краткой информации о локациях для отображения на карте.
"""
queryset = Location.objects.all().prefetch_related('small_main_photo')
queryset = Location.objects.all().select_related('small_main_photo')
serializer_class = LocationMapSerializer
permission_classes = (AllowAny,)
pagination_class = LimitOffsetPagination
filter_backends = (DjangoFilterBackend,)
filterset_class = LocationFilter

def get_queryset(self):
return super().get_queryset().annotate(
rating=Avg('spots__orders__reviews__rating')
)
5 changes: 0 additions & 5 deletions api_spot/api/views/order.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.conf import settings
from django.shortcuts import get_object_or_404
from django_filters.rest_framework import DjangoFilterBackend
from drf_spectacular.utils import extend_schema
Expand All @@ -14,7 +13,6 @@
OrderGetSerializer, OrderSerializer, OrderUpdateSerializer,
)
from api.services.orders import order_cancel_email, order_confirmation_email
from api.tasks import change_status_task
from spots.constants import CANCEL, PAID, WAIT_PAY
from spots.models import Order

Expand All @@ -38,9 +36,6 @@ def get_serializer_class(self):

def perform_create(self, serializer):
instance = serializer.save()
change_status_task.apply_async(
args=[instance.id], countdown=settings.TIME_CHANGE_STATUS
)
order_confirmation_email(instance)

def update(self, request, location_id, spot_id, pk, *args, **kwargs):
Expand Down
15 changes: 1 addition & 14 deletions api_spot/spots/models/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
DAYS_CHOICES, END_CHOICES, LAT_MAX, LAT_MIN, LAT_MSG_ERROR, LONG_MAX,
LONG_MIN, LONG_MSG_ERROR, MEETING_ROOM, NAME_CACHE_MEETING_ROOM,
NAME_CACHE_WORKSPACE, START_CHOICES, WORK_SPACE,

)
from spots.services import count_spots, get_low_price, get_rating_location
from spots.services import count_spots


class Location(models.Model):
Expand Down Expand Up @@ -117,18 +116,6 @@ def count_meeting_room(self, *args, **kwargs) -> int:
"""
return count_spots(self, MEETING_ROOM, NAME_CACHE_MEETING_ROOM)

def rating(self, *args, **kwargs) -> float:
"""
Получение среднего рейтинга по отзывам.
"""
return get_rating_location(self)

def low_price(self, *args, **kwargs) -> int:
"""
Минимальная цена.
"""
return get_low_price(self)

def get_full_address_str(self) -> str:
"""
Полный адрес.
Expand Down
15 changes: 12 additions & 3 deletions api_spot/spots/models/order.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import datetime
from decimal import Decimal

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.db import models, transaction

import spots.constants as constants
from spots.models.spot import Spot
Expand Down Expand Up @@ -87,8 +88,16 @@ def clean(self) -> None:
return super().clean()

def save(self, *args, **kwargs) -> None:
from ..tasks import change_status_task

self.get_bill()
return super().save(*args, **kwargs)
if not self.pk:
super().save(*args, **kwargs)
transaction.on_commit(lambda: change_status_task.apply_async(
args=[self.pk], countdown=settings.TIME_CHANGE_STATUS
))
else:
super().save(*args, **kwargs)

class Meta:
"""Класс Meta для Order описание метаданных."""
Expand All @@ -97,4 +106,4 @@ class Meta:
ordering = ('date', 'start_time')

def __str__(self) -> str:
return f'Локация = {self.spot.location} , спот = {self.spot}'
return f'Локация id = {self.spot.location.id}, спот={self.spot.id}'
19 changes: 17 additions & 2 deletions api_spot/spots/tasks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import datetime

from django.shortcuts import get_object_or_404
from celery import shared_task

from api_spot.celery import app
from spots.constants import FINISH, PAID
from spots.models import Order
from spots.constants import FINISH, NOT_PAID, PAID, WAIT_PAY

from .models.order import Order


@shared_task
def change_status_task(order_id: int) -> str:
"""Таска изменения статуса после n секнуд."""
order = get_object_or_404(Order, pk=order_id)
if order.status != PAID and order.status == WAIT_PAY:
order.status = NOT_PAID
order.save()
return f'Cтатус у {order_id} изменен'
return f'Cтатус у {order_id} не изменен'


@app.task
Expand Down
Loading

0 comments on commit 0188a49

Please sign in to comment.