Skip to content

Commit 0393af4

Browse files
Merge pull request #24 from usermicrodevices/develop
auto reset product admin internal cache
2 parents 741201b + 94c2919 commit 0393af4

4 files changed

Lines changed: 81 additions & 30 deletions

File tree

core/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ def registration(self, request, queryset):
438438
for r in Record.objects.filter(doc=it):
439439
if not Register.objects.filter(rec=r).exists():
440440
try:
441-
Register(rec=r).save()
441+
obj, created = Register.objects.get_or_create(rec=r)
442442
except Exception as e:
443443
self.loge(e)
444444
break

core/models.py

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from django.core.cache import caches
1414
from django.db.utils import IntegrityError
1515
from django.apps import apps as django_apps
16+
from django.contrib import admin
1617
try:
1718
from zoneinfo import available_timezones, ZoneInfo
1819
except:
@@ -161,6 +162,30 @@ def on_rec_post_save(sender, **kwargs):
161162
Register(rec=instance).save()
162163
except Exception as e:
163164
instance.loge(e)
165+
last_doc = Doc.objects.filter(id__in=Record.objects.filter(product=instance.product).values('doc_id')).order_by('registered_at').last()
166+
if last_doc and last_doc.registered_at <= instance.doc.registered_at:
167+
updatefields = []
168+
if settings.BEHAVIOR_COST.get('register_change_referece', False):
169+
if instance.cost and instance.cost != instance.product.cost:
170+
instance.product.cost = instance.cost
171+
updatefields.append('cost')
172+
if settings.BEHAVIOR_PRICE.get('register_change_referece', False):
173+
if instance.price and instance.price != instance.product.price:
174+
instance.product.price = instance.price
175+
updatefields.append('price')
176+
if updatefields:
177+
try:
178+
instance.product.save(update_fields=updatefields)
179+
except Exception as e:
180+
instance.loge(e)
181+
try:
182+
product_admin = admin.site.get_model_admin(get_model('refs.Product'))
183+
except Exception as e:
184+
instance.loge(e)
185+
else:
186+
if product_admin and hasattr(product_admin, '__objs__'):
187+
if instance.product_id in product_admin.__objs__:
188+
del product_admin.__objs__[instance.product_id]
164189

165190

166191
class Register(CustomAbstractModel):
@@ -171,20 +196,21 @@ class Meta:
171196
verbose_name_plural = f'✅{_("Registers")}'
172197
ordering = ['-id']
173198

174-
@receiver(post_save, sender=Register)
175-
def on_reg_post_save(sender, **kwargs):
176-
instance: Register = kwargs['instance']
177-
updatefields = []
178-
if settings.BEHAVIOR_COST.get('register_change_referece', False):
179-
if instance.rec.cost != instance.rec.product.cost:
180-
instance.rec.product.cost = instance.rec.cost
181-
updatefields.append('cost')
182-
if settings.BEHAVIOR_PRICE.get('register_change_referece', False):
183-
if instance.rec.price != instance.rec.product.price:
184-
instance.rec.product.price = instance.rec.price
185-
updatefields.append('price')
186-
if updatefields:
199+
def reset_admin_product_cache(self):
187200
try:
188-
instance.rec.product.save(update_fields=updatefields)
201+
product_admin = admin.site.get_model_admin(get_model('refs.Product'))
189202
except Exception as e:
190-
instance.loge(e)
203+
self.loge(e)
204+
else:
205+
if product_admin and hasattr(product_admin, '__objs__'):
206+
if self.rec.product_id in product_admin.__objs__:
207+
del product_admin.__objs__[self.rec.product_id]
208+
self.logi(product_admin.__objs__)
209+
210+
@receiver(post_save, sender=Register)
211+
def on_reg_post_save(sender, **kwargs):
212+
kwargs['instance'].reset_admin_product_cache()
213+
214+
@receiver(post_delete, sender=Register)
215+
def on_reg_post_delete(sender, **kwargs):
216+
kwargs['instance'].reset_admin_product_cache()

locale/ru_RU/LC_MESSAGES/django.po

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,3 +592,9 @@ msgstr "создан документ"
592592

593593
msgid "count records"
594594
msgstr "количество позиций"
595+
596+
msgid "reset cached values"
597+
msgstr "сбросить кэшированные значения"
598+
599+
msgid "cancel registration"
600+
msgstr "отмена регистрации"

refs/admin.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from django.db import connections
2222
from django.contrib.admin.models import LogEntry
2323
from django.contrib.admin.widgets import AutocompleteSelect
24+
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
2425
from django.shortcuts import render
2526
from django.views.generic.edit import FormView
2627
from django.core.cache import caches
@@ -678,11 +679,21 @@ class ProductAdmin(CustomModelAdmin):
678679
list_select_related = ('tax', 'model', 'group')
679680
list_filter = (ProductGroupFilter, ProductManufacturerFilter, ProductModelFilter, TaxFilter)
680681
autocomplete_fields = ('tax', 'model', 'group', 'barcodes', 'qrcodes')
681-
actions = ('from_xls', 'to_xls', 'price_to_xls', 'barcode_to_svg', 'fix_barcodes')
682+
actions = ('from_xls', 'to_xls', 'price_to_xls', 'barcode_to_svg', 'fix_barcodes', 'reset_cached')
682683

683684
#class Media:
684685
#js = ['admin/js/autocomplete.js', 'admin/js/vendor/select2/select2.full.js']
685686

687+
def changelist_view(self, request, extra_context=None):
688+
if 'action' in request.POST and request.POST['action'] == 'reset_cached':
689+
if not request.POST.getlist(ACTION_CHECKBOX_NAME):
690+
post = request.POST.copy()
691+
p = Product.objects.first()
692+
if p:
693+
post.update({ACTION_CHECKBOX_NAME: str(p.id)})
694+
request._set_post(post)
695+
return super().changelist_view(request, extra_context)
696+
686697
def get_last_reg(self, obj):
687698
if obj.id in self.__objs__ and 'lreg' in self.__objs__[obj.id]:
688699
return self.__objs__[obj.id]['lreg']
@@ -742,21 +753,25 @@ def get_qrcodes(self, obj):
742753
return format_html('<details><summary>{}</summary>{}</details>', idxs[0][1], content)
743754
get_qrcodes.short_description = _('Qr Codes')
744755

756+
def refresh_count_from_reg(self, obj):
757+
if obj.id not in self.__objs__:
758+
self.__objs__[obj.id] = {}
759+
SumIncome=Sum('rec__count', filter=Q(rec__doc__type__income=True), default=0)
760+
SumExpense=Sum('rec__count', filter=Q(rec__doc__type__income=False), default=0)
761+
try:
762+
self.__objs__[obj.id]['count'] = get_model('core.Register').objects.filter(rec__product_id=obj.id).aggregate(count=SumIncome-SumExpense)['count']
763+
except Exception as e:
764+
self.loge(e)
765+
else:
766+
self.logi('FROM BASE', self.__objs__[obj.id]['count'])
767+
return self.__objs__[obj.id]['count']
768+
return 0
769+
745770
def get_count_from_reg(self, obj):
746771
if obj.id in self.__objs__ and 'count' in self.__objs__[obj.id]:
772+
self.logi('FROM BUFFER', self.__objs__[obj.id]['count'])
747773
return self.__objs__[obj.id]['count']
748-
else:
749-
if obj.id not in self.__objs__:
750-
self.__objs__[obj.id] = {}
751-
SumIncome=Sum('rec__count', filter=Q(rec__doc__type__income=True), default=0)
752-
SumExpense=Sum('rec__count', filter=Q(rec__doc__type__income=False), default=0)
753-
try:
754-
self.__objs__[obj.id]['count'] = get_model('core.Register').objects.filter(rec__product_id=obj.id).aggregate(count=SumIncome-SumExpense)['count']
755-
except Exception as e:
756-
self.loge(e)
757-
else:
758-
return self.__objs__[obj.id]['count']
759-
return 0
774+
return self.refresh_count_from_reg(obj)
760775

761776
def count(self, obj):
762777
result = self.get_count_from_reg(obj)
@@ -800,6 +815,10 @@ def get_group(self, obj):
800815
get_group.short_description = _('Product Group')
801816
get_group.admin_order_field = 'group'
802817

818+
def reset_cached(self, request, queryset, **kwargs):
819+
self.__objs__ = {}
820+
reset_cached.short_description = f'↻💦{_("reset cached values")}'
821+
803822
def from_xls(self, request, queryset, **kwargs):
804823
from barcode import EAN13
805824
from transliterate import slugify
@@ -945,7 +964,7 @@ def barcode_to_svg(self, request, queryset):
945964
from barcode import EAN13
946965
from barcode.writer import SVGWriter
947966
def eval_dim(val, n, m='-'):
948-
v = re.findall('\d+\.\d+', val)[0]
967+
v = re.findall(r'\d+\.\d+', val)[0]
949968
suffix = val.replace(v, '')
950969
return f'{eval(f'{v}{m}{n}')}{suffix}'
951970
svgs = ''

0 commit comments

Comments
 (0)