Merge branch 'master' into storefront-nuxt

This commit is contained in:
Egor Pavlovich Gorbunov 2026-03-02 01:31:57 +03:00
commit 783fca1f28
5 changed files with 44 additions and 34 deletions

View file

@ -1,7 +1,7 @@
from django.utils.translation import gettext_lazy as _
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import status
from drf_spectacular.utils import OpenApiParameter, extend_schema, inline_serializer
from rest_framework import serializers, status
from engine.core.docs.drf import BASE_ERRORS
from engine.core.serializers import (
@ -759,6 +759,16 @@ PRODUCT_SCHEMA = {
"retrieve a list of products by identifier type (uuid, slug, or sku). "
"Send a POST request with `identificator_type` and `identificators` (list of values)."
),
request=inline_serializer(
name="ExactProductsRequest",
fields={
"identificator_type": serializers.ChoiceField(
choices=["uuid", "slug", "sku"]
),
"identificators": serializers.ListField(child=serializers.CharField()),
},
),
parameters=[],
responses={
status.HTTP_200_OK: ProductSimpleSerializer(many=True),
**BASE_ERRORS,

View file

@ -15,11 +15,10 @@ from engine.core.graphene.object_types import (
BulkProductInput,
FeedbackType,
OrderType,
ProductType,
SearchResultsType,
WishlistType,
)
from engine.core.models import Address, Order, OrderProduct, Product, Wishlist
from engine.core.models import Address, Order, OrderProduct, Wishlist
from engine.core.utils import format_attributes, is_url_safe
from engine.core.utils.caching import web_cache
from engine.core.utils.emailing import contact_us_email
@ -575,31 +574,6 @@ class BuyProduct(Mutation):
)
class RetrieveExactProducts(Mutation):
class Meta:
description = _("retrieve exact products by identificator")
class Arguments:
identificator_type = String(required=True)
identificators = List(String, required=True)
products = List(ProductType, required=True)
def mutate(self, info, identificator_type: str, identificators: list[str]):
match identificator_type:
case "uuid":
products = Product.objects.filter(uuid__in=identificators)
case "slug":
products = Product.objects.filter(slug__in=identificators)
case "sku":
products = Product.objects.filter(sku__in=identificators)
case _:
raise BadRequest(
_("identificator_type must be one of: uuid, slug, sku")
)
return RetrieveExactProducts(products=products) # ty: ignore[unknown-argument]
# noinspection PyUnusedLocal,PyTypeChecker
class FeedbackProductAction(Mutation):
class Meta:

View file

@ -5,7 +5,7 @@ from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.db.models import Case, Exists, IntegerField, OuterRef, Q, Value, When
from django.utils import timezone
from graphene import Field, List, ObjectType, Schema
from graphene import Argument, Field, List, ObjectType, Schema, String
from graphene_django.filter import (
DjangoFilterConnectionField, # ty:ignore[possibly-missing-import]
)
@ -41,7 +41,6 @@ from engine.core.graphene.mutations import (
RemoveOrderProductsOfAKind,
RemoveWishlistProduct,
RequestCursedURL,
RetrieveExactProducts,
Search,
)
from engine.core.graphene.object_types import (
@ -135,6 +134,27 @@ class Query(ObjectType):
promocodes = DjangoFilterConnectionField(PromoCodeType)
brands = DjangoFilterConnectionField(BrandType, filterset_class=BrandFilter)
posts = DjangoFilterConnectionField(PostType, filterset_class=PostFilter)
retrieve_exact_products = List(
ProductType,
identificator_type=Argument(String, required=True),
identificators=Argument(List(String), required=True),
)
@staticmethod
def resolve_retrieve_exact_products(
_parent, _info, identificator_type: str, identificators: list[str]
):
from graphql import GraphQLError
match identificator_type:
case "uuid":
return Product.objects.filter(uuid__in=identificators)
case "slug":
return Product.objects.filter(slug__in=identificators)
case "sku":
return Product.objects.filter(sku__in=identificators)
case _:
raise GraphQLError("identificator_type must be one of: uuid, slug, sku")
@staticmethod
def resolve_parameters(_parent, _info):
@ -385,7 +405,6 @@ class Mutation(ObjectType):
bulk_order_action = BulkOrderAction.Field()
bulk_wishlist_action = BulkWishlistAction.Field()
feedback_product_action = FeedbackProductAction.Field()
retrieve_exact_products = RetrieveExactProducts.Field()
deposit = Deposit.Field()
obtain_jwt_token = ObtainJSONWebToken.Field()
refresh_jwt_token = RefreshJSONWebToken.Field()

View file

@ -4,10 +4,18 @@ from typing import Any, Mapping
from django import forms
from django.core.files.uploadedfile import UploadedFile
from django.forms.renderers import BaseRenderer
from django.forms.widgets import PasswordInput
from django.utils.datastructures import MultiValueDict
from django.utils.safestring import SafeString
class PasswordInputRenderValue(PasswordInput):
"""PasswordInput with render_value=True so constance re-displays the current value."""
def __init__(self, attrs=None):
super().__init__(attrs=attrs, render_value=True)
class JSONTableWidget(forms.Widget):
template_name = "json_table_widget.html"

View file

@ -20,8 +20,7 @@ CONSTANCE_ADDITIONAL_FIELDS = {
"django.forms.CharField",
{
"required": False,
"widget": "django.forms.PasswordInput",
"widget_attrs": {"render_value": True},
"widget": "engine.core.widgets.PasswordInputRenderValue",
},
],
}