Features: 1) Add RecentProductConnection to support recently viewed products in GraphQL; 2) Implement recently_viewed field in UserType with reverse-chronological product ordering; 3) Add recently_viewed field to UserSerializer and return data with ProductSimpleSerializer.
Fixes: 1) Fix `resolve_recently_viewed` to handle empty UUIDs and avoid breaking queries. Extra: Refactor imports in `graphene/object_types.py` and `serializers.py` for better clarity; Adjust minor formatting in `TokenObtainSerializer`.
This commit is contained in:
parent
f76b000e07
commit
89f6594751
2 changed files with 37 additions and 6 deletions
|
|
@ -3,8 +3,10 @@ from django.utils.translation import gettext_lazy as _
|
|||
from graphene import Field, List, String, relay
|
||||
from graphene.types.generic import GenericScalar
|
||||
from graphene_django import DjangoObjectType
|
||||
from graphql_relay.connection.array_connection import connection_from_array
|
||||
|
||||
from core.graphene.object_types import OrderType, WishlistType
|
||||
from core.graphene.object_types import OrderType, ProductType, WishlistType
|
||||
from core.models import Product
|
||||
from evibes.settings import LANGUAGE_CODE, LANGUAGES
|
||||
from payments.graphene.object_types import BalanceType
|
||||
from vibes_auth.models import User
|
||||
|
|
@ -26,8 +28,16 @@ class PermissionType(DjangoObjectType):
|
|||
filter_fields = ["name", "id"]
|
||||
|
||||
|
||||
class RecentProductConnection(relay.Connection):
|
||||
class Meta:
|
||||
node = ProductType
|
||||
|
||||
|
||||
class UserType(DjangoObjectType):
|
||||
recently_viewed = GenericScalar(description=_("recently viewed products' UUIDs"))
|
||||
recently_viewed = relay.ConnectionField(
|
||||
RecentProductConnection,
|
||||
description=_("the products this user has viewed most recently (max 48), in reverse‐chronological order"),
|
||||
)
|
||||
groups = List(lambda: GroupType, description=_("groups"))
|
||||
user_permissions = List(lambda: PermissionType, description=_("permissions"))
|
||||
orders = List(lambda: OrderType, description=_("orders"))
|
||||
|
|
@ -89,8 +99,23 @@ class UserType(DjangoObjectType):
|
|||
def resolve_orders(self, info):
|
||||
return self.orders.all() if self.orders.count() >= 1 else []
|
||||
|
||||
def resolve_recently_viewed(self, info):
|
||||
return [] or self.recently_viewed
|
||||
def resolve_recently_viewed(self, info, **kwargs):
|
||||
uuid_list = self.recently_viewed or []
|
||||
|
||||
if not uuid_list:
|
||||
return connection_from_array([], kwargs)
|
||||
|
||||
qs = Product.objects.filter(uuid__in=uuid_list)
|
||||
|
||||
products_by_uuid = {str(p.uuid): p for p in qs}
|
||||
|
||||
ordered_products = [
|
||||
products_by_uuid[u]
|
||||
for u in uuid_list
|
||||
if u in products_by_uuid
|
||||
]
|
||||
|
||||
return connection_from_array(ordered_products, kwargs)
|
||||
|
||||
def resolve_groups(self, info):
|
||||
return self.groups.all() if self.groups.count() >= 1 else []
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ from rest_framework_simplejwt.settings import api_settings
|
|||
from rest_framework_simplejwt.token_blacklist.models import BlacklistedToken
|
||||
from rest_framework_simplejwt.tokens import RefreshToken, Token, UntypedToken
|
||||
|
||||
from core.models import Product
|
||||
from core.serializers import ProductSimpleSerializer
|
||||
from core.utils.security import is_safe_key
|
||||
from evibes import settings
|
||||
from vibes_auth.models import User
|
||||
|
|
@ -32,6 +34,7 @@ class UserSerializer(ModelSerializer):
|
|||
avatar_url = SerializerMethodField(required=False, read_only=True)
|
||||
password = CharField(write_only=True, required=False)
|
||||
is_staff = BooleanField(read_only=True)
|
||||
recently_viewed = SerializerMethodField(required=False, read_only=True)
|
||||
|
||||
@staticmethod
|
||||
def get_avatar_url(obj) -> str:
|
||||
|
|
@ -84,6 +87,9 @@ class UserSerializer(ModelSerializer):
|
|||
validate_password(attrs["password"])
|
||||
return attrs
|
||||
|
||||
def get_recently_viewed(self, obj) -> ProductSimpleSerializer.data:
|
||||
return ProductSimpleSerializer(Product.objects.filter(uuid__in=([] or obj.recently_viewed)), many=True).data
|
||||
|
||||
|
||||
class TokenObtainSerializer(Serializer):
|
||||
username_field = User.USERNAME_FIELD
|
||||
|
|
@ -177,8 +183,8 @@ class TokenVerifySerializer(Serializer):
|
|||
token = UntypedToken(attrs["token"])
|
||||
|
||||
if (
|
||||
api_settings.BLACKLIST_AFTER_ROTATION
|
||||
and "rest_framework_simplejwt.token_blacklist" in settings.INSTALLED_APPS
|
||||
api_settings.BLACKLIST_AFTER_ROTATION
|
||||
and "rest_framework_simplejwt.token_blacklist" in settings.INSTALLED_APPS
|
||||
):
|
||||
jti = token.get(api_settings.JTI_CLAIM)
|
||||
if BlacklistedToken.objects.filter(token__jti=jti).exists():
|
||||
|
|
|
|||
Loading…
Reference in a new issue