Features: 1) Add caching mechanism for 'recently_viewed' functionality.

Fixes: 1) Remove 'recently_viewed' ManyToManyField from User model and related migration; 2) Correct handling of product addition in 'recently_viewed' logic.

Extra: Refactor 'recently_viewed' to use cache instead of database field; cleanup unused imports and model attributes.
This commit is contained in:
Egor Pavlovich Gorbunov 2025-05-19 15:09:45 +03:00
parent c3c2222d99
commit 3590dbbe2b
3 changed files with 15 additions and 17 deletions

View file

@ -69,7 +69,7 @@ class UserAdmin(BaseUserAdmin, BasicModelAdmin):
}, },
), ),
(_("important dates"), {"fields": ("last_login", "date_joined")}), (_("important dates"), {"fields": ("last_login", "date_joined")}),
(_("additional info"), {"fields": ("recently_viewed", "language", "attributes")}), (_("additional info"), {"fields": ("language", "attributes")}),
) )
add_fieldsets = ( add_fieldsets = (
( (
@ -90,7 +90,7 @@ class UserAdmin(BaseUserAdmin, BasicModelAdmin):
"is_subscribed", "is_subscribed",
) )
ordering = ("email",) ordering = ("email",)
readonly_fields = ("recently_viewed", "password") readonly_fields = ("password")
form = UserForm form = UserForm
def get_queryset(self, request): def get_queryset(self, request):

View file

@ -86,9 +86,6 @@ class Migration(migrations.Migration):
help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.',
related_name='user_set', related_query_name='user', to='auth.group', related_name='user_set', related_query_name='user', to='auth.group',
verbose_name='groups')), verbose_name='groups')),
('recently_viewed',
models.ManyToManyField(blank=True, help_text='recently viewed products', to='core.product',
verbose_name='recently viwed')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.',
related_name='user_set', related_query_name='user', related_name='user_set', related_query_name='user',
to='auth.permission', verbose_name='user permissions')), to='auth.permission', verbose_name='user permissions')),

View file

@ -2,13 +2,13 @@ from uuid import uuid4
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import Group as BaseGroup from django.contrib.auth.models import Group as BaseGroup
from django.core.cache import cache
from django.db.models import ( from django.db.models import (
BooleanField, BooleanField,
CharField, CharField,
EmailField, EmailField,
ImageField, ImageField,
JSONField, JSONField,
ManyToManyField,
UUIDField, UUIDField,
) )
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -65,12 +65,6 @@ class User(AbstractUser, NiceModel):
is_subscribed = BooleanField( is_subscribed = BooleanField(
verbose_name=_("is_subscribed"), help_text=_("user's newsletter subscription status"), default=False verbose_name=_("is_subscribed"), help_text=_("user's newsletter subscription status"), default=False
) )
recently_viewed = ManyToManyField(
"core.Product",
verbose_name=_("recently viwed"),
blank=True,
help_text=_("recently viewed products"),
)
activation_token = UUIDField(default=uuid4, verbose_name=_("activation token")) activation_token = UUIDField(default=uuid4, verbose_name=_("activation token"))
language = CharField(choices=LANGUAGES, default=LANGUAGE_CODE, null=False, blank=False, max_length=7) language = CharField(choices=LANGUAGES, default=LANGUAGE_CODE, null=False, blank=False, max_length=7)
@ -81,12 +75,19 @@ class User(AbstractUser, NiceModel):
objects = UserManager() objects = UserManager()
def add_to_recently_viewed(self, product_uuid): def add_to_recently_viewed(self, product_uuid):
if not self.recently_viewed.filter(uuid=product_uuid).exists(): recently_viewed = self.recently_viewed
if not self.recently_viewed.count() >= 48: if not product_uuid in recently_viewed:
self.recently_viewed.add(product_uuid) if not len(recently_viewed) >= 48:
recently_viewed.append(product_uuid)
cache.set(f"user_{self.uuid}_rv", recently_viewed)
else: else:
self.recently_viewed.remove(self.recently_viewed.first()) recently_viewed.pop(0)
self.recently_viewed.add(product_uuid) recently_viewed.append(product_uuid)
cache.set(f"user_{self.uuid}_rv", recently_viewed)
@property
def recently_viewed(self):
return [] or cache.get(f"user_{self.uuid}_rv")
def check_token(self, token): def check_token(self, token):
return str(token) == str(self.activation_token) return str(token) == str(self.activation_token)