Skip to content

Commit

Permalink
Merge pull request #248 from healthy-food-and-dietary-products/fix/sh…
Browse files Browse the repository at this point in the history
…oppingcart_product_photo_full_paths

Fix/shoppingcart product photo full paths
  • Loading branch information
juliana-str authored Feb 6, 2024
2 parents 31daad0 + 44ccab7 commit edc62a5
Show file tree
Hide file tree
Showing 17 changed files with 413 additions and 174 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/good_food_workflow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ jobs:
python -m flake8
- name: Test with pytest
run: |
cd backend
pytest
pytest backend/tests/
- name: send message
if: ${{ github.ref != 'refs/heads/main' }}
uses: appleboy/telegram-action@master
Expand Down
18 changes: 12 additions & 6 deletions backend/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
from products.models import Product


class CharFilterInFilter(rf_filters.BaseInFilter, rf_filters.CharFilter):
"""Custom char filter allowing comma-separated incoming values."""

pass


class ProductFilter(rf_filters.FilterSet):
"""Class for filtering products."""

name = rf_filters.CharFilter(method="startswith_contains_union_method")
category = rf_filters.AllValuesMultipleFilter(field_name="category__slug")
subcategory = rf_filters.AllValuesMultipleFilter(field_name="subcategory__slug")
producer = rf_filters.AllValuesMultipleFilter(field_name="producer__slug")
components = rf_filters.AllValuesMultipleFilter(field_name="components__slug")
tags = rf_filters.AllValuesMultipleFilter(field_name="tags__slug")
promotions = rf_filters.AllValuesMultipleFilter(field_name="promotions__slug")
category = CharFilterInFilter(field_name="category__slug")
subcategory = CharFilterInFilter(field_name="subcategory__slug")
producer = CharFilterInFilter(field_name="producer__slug")
components = CharFilterInFilter(field_name="components__slug")
tags = CharFilterInFilter(field_name="tags__slug")
promotions = CharFilterInFilter(field_name="promotions__slug")
is_favorited = rf_filters.NumberFilter(method="product_boolean_methods")
min_price = rf_filters.NumberFilter(method="get_min_price")
max_price = rf_filters.NumberFilter(method="get_max_price")
Expand Down
2 changes: 1 addition & 1 deletion backend/api/orders_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def coupon_apply(self, request):
code = request.data["code"]
try:
coupon = Coupon.objects.get(
Q(code__iexact=code),
Q(code__exact=code),
Q(is_active=True),
Q(start_time__lte=now) | Q(start_time__isnull=True),
Q(end_time__gte=now) | Q(end_time__isnull=True),
Expand Down
11 changes: 2 additions & 9 deletions backend/api/products_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
Tag,
)

COUPON_PROMOTION_TYPE_API_ERROR_MESSAGE = (
f"Указан неверный тип промоакции, нужно выбрать {Promotion.COUPON}."
)
RATING_DECIMAL_PLACES = 1


Expand Down Expand Up @@ -516,6 +513,8 @@ def setup_eager_loading(cls, queryset, user):
class CouponSerializer(serializers.ModelSerializer):
"""Serializer for coupons representation."""

promotion_type = serializers.ReadOnlyField()

class Meta:
model = Coupon
fields = (
Expand All @@ -533,12 +532,6 @@ class Meta:
"image",
)

def validate_promotion_type(self, value):
"""Checks that promotion_type is correct."""
if value != Promotion.COUPON:
raise serializers.ValidationError(COUPON_PROMOTION_TYPE_API_ERROR_MESSAGE)
return value


class CouponApplySerializer(serializers.ModelSerializer):
"""Serializer to apply coupon promoaction to the order."""
Expand Down
12 changes: 12 additions & 0 deletions backend/api/products_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,12 @@ class CouponViewSet(DestroyWithPayloadMixin, viewsets.ModelViewSet):
serializer_class = CouponSerializer
permission_classes = [IsAdminOrReadOnly]

@transaction.atomic
def perform_create(self, serializer):
"""Sets the correct promotion_type during coupon creation."""
serializer.save(promotion_type=Promotion.COUPON)
return super().perform_create(serializer)


@method_decorator(
name="list",
Expand Down Expand Up @@ -664,13 +670,19 @@ def get_queryset(self):

@transaction.atomic
def perform_create(self, serializer):
"""
Sets the correct category for the given subcategory during product creation.
"""
subcategory_id = serializer._kwargs["data"]["subcategory"]
subcategory = Subcategory.objects.get(id=subcategory_id)
serializer.save(category=subcategory.parent_category)
return super().perform_create(serializer)

@transaction.atomic
def perform_update(self, serializer):
"""
Sets the correct category for the given subcategory during product editing.
"""
subcategory_id = serializer._kwargs["data"].get("subcategory")
if subcategory_id:
subcategory = Subcategory.objects.get(id=subcategory_id)
Expand Down
2 changes: 2 additions & 0 deletions backend/api/reviews_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,12 @@ def get_queryset(self):
).select_related("product", "author")

def perform_create(self, serializer):
"""Sets the correct author and product during review creation."""
product = get_object_or_404(Product, pk=self.kwargs.get("product_id"))
serializer.save(author=self.request.user, product=product)

def perform_update(self, serializer):
"""Updates pub_date and was_edited fields during review editing."""
serializer.save(pub_date=timezone.now(), was_edited=True)
return super().perform_update(serializer)

Expand Down
18 changes: 17 additions & 1 deletion backend/api/users_serializers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
from dateutil.relativedelta import relativedelta
from django.contrib.auth import get_user_model
from django.db import transaction
from django.utils import timezone
from djoser.serializers import UserCreateSerializer as DjoserUserCreateSerializer
from djoser.serializers import UserDeleteSerializer as DjoserUserDeleteSerializer
from djoser.serializers import UserSerializer as DjoserUserSerializer
from rest_framework import serializers
from rest_framework.validators import UniqueValidator

from users.models import Address
from users.models import (
BIRTH_DATE_TOO_OLD_ERROR_MESSAGE,
BIRTH_DATE_TOO_YOUNG_ERROR_MESSAGE,
MAX_USER_AGE,
MIN_USER_AGE,
Address,
)
from users.utils import city_choices

User = get_user_model()
Expand Down Expand Up @@ -69,6 +77,14 @@ class Meta:
"photo",
)

def validate_birth_date(self, value):
now = timezone.now()
if value and value + relativedelta(years=MIN_USER_AGE) > now.date():
raise serializers.ValidationError(BIRTH_DATE_TOO_YOUNG_ERROR_MESSAGE)
if value and value + relativedelta(years=MAX_USER_AGE) < now.date():
raise serializers.ValidationError(BIRTH_DATE_TOO_OLD_ERROR_MESSAGE)
return value

def get_address_quantity(self, obj) -> int:
return obj.addresses.count()

Expand Down
21 changes: 11 additions & 10 deletions backend/orders/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@

@admin.register(Delivery)
class DeliveryAdmin(admin.ModelAdmin):
list_display = ("id", "delivery_point")
list_display_links = ("delivery_point",)
list_display = ["id", "delivery_point"]
list_display_links = ["delivery_point"]


class OrderProductInline(admin.TabularInline):
model = OrderProduct
list_display = ("id", "product", "quantity")
list_editable = ("product", "quantity")
list_display = ["id", "product", "quantity"]
list_editable = ["product", "quantity"]


@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
inlines = (OrderProductInline,)
list_display = (
inlines = [OrderProductInline]
list_display = [
"id",
"order_number",
"user",
Expand All @@ -30,10 +30,11 @@ class OrderAdmin(admin.ModelAdmin):
"total_price",
"coupon_applied",
"coupon_discount",
)
list_display_links = ("ordering_date",)
list_editable = ("payment_method", "delivery_method")
list_filter = ("status", "ordering_date")
]
list_display_links = ["ordering_date"]
list_editable = ["payment_method", "delivery_method"]
list_filter = ["status", "ordering_date"]
readonly_fields = ["coupon_applied", "coupon_discount"]

def get_queryset(self, request):
queryset = super().get_queryset(request)
Expand Down
4 changes: 1 addition & 3 deletions backend/orders/shopping_carts.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
from django.utils import timezone

from core.loggers import logger
from products.models import Coupon, Product

PRICE_DECIMAL_PLACES = 2
from products.models import PRICE_DECIMAL_PLACES, Coupon, Product


class ShopCart(object):
Expand Down
Loading

0 comments on commit edc62a5

Please sign in to comment.