Refactor card badge and multiselect template tags to properly implement and/or improve caching and context handling
- Updated `card_badge` and `card_multiselect` template tags to utilize `reverse_lazy` for URL resolution. - Enhanced caching mechanisms in `card_badge.html` and `card_multiselect.html` to improve performance. - Introduced a new template `_card_multiselect_options.html` for rendering multiselect options. - Improved context management in `card_multiselect` to handle selected cards and dynamic placeholders. - Added error handling for query hashing in `card_multiselect` to ensure robustness. - Updated `trade_offer_tags` to optimize database queries using `select_related` for related objects.
This commit is contained in:
parent
7d94dc001f
commit
4e50e1545c
10 changed files with 234 additions and 163 deletions
|
|
@ -5,6 +5,5 @@ class TradesConfig(AppConfig):
|
|||
name = "trades"
|
||||
|
||||
def ready(self):
|
||||
# This import registers the signal handlers defined in trades/signals.py,
|
||||
# ensuring that denormalized field updates occur whenever related objects change.
|
||||
# Implicitly connect signal handlers decorated with @receiver.
|
||||
import trades.signals
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.db.models.signals import post_save, post_delete, pre_save
|
||||
from django.dispatch import receiver
|
||||
from django.db.models import F
|
||||
from trades.models import TradeOfferHaveCard, TradeOfferWantCard, TradeAcceptance
|
||||
from trades.models import TradeOfferHaveCard, TradeOfferWantCard, TradeAcceptance, TradeOffer
|
||||
from django.db import transaction
|
||||
from accounts.models import CustomUser
|
||||
from datetime import timedelta
|
||||
|
|
@ -12,6 +12,8 @@ from django.core.mail import send_mail
|
|||
from django.conf import settings
|
||||
from django.template.loader import render_to_string
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.cache import cache
|
||||
import logging
|
||||
|
||||
POSITIVE_STATES = [
|
||||
TradeAcceptance.AcceptanceState.ACCEPTED,
|
||||
|
|
@ -178,7 +180,7 @@ def trade_acceptance_reputation_update(sender, instance, created, **kwargs):
|
|||
state transitions for TradeAcceptance.
|
||||
|
||||
- THANKED_BY_BOTH: both the initiator and the acceptor receive +1 when transitioning
|
||||
into this state, and -1 when leaving it.
|
||||
into this state, and -1 when leaving it.
|
||||
- REJECTED_BY_INITIATOR: only the acceptor gets -1 when transitioning into it (and +1 when leaving it).
|
||||
- REJECTED_BY_ACCEPTOR: only the initiator gets -1 when transitioning into it (and +1 when leaving it).
|
||||
|
||||
|
|
@ -259,4 +261,18 @@ def trade_acceptance_reputation_delete(sender, instance, **kwargs):
|
|||
if instance.state == TradeAcceptance.AcceptanceState.REJECTED_BY_ACCEPTOR:
|
||||
CustomUser.objects.filter(pk=instance.trade_offer.initiated_by.user.pk).update(
|
||||
reputation_score=F("reputation_score") + 1
|
||||
)
|
||||
)
|
||||
|
||||
@receiver(post_save, sender=TradeOfferHaveCard)
|
||||
@receiver(post_delete, sender=TradeOfferHaveCard)
|
||||
@receiver(post_save, sender=TradeOfferWantCard)
|
||||
@receiver(post_delete, sender=TradeOfferWantCard)
|
||||
@receiver(post_save, sender=TradeAcceptance)
|
||||
@receiver(post_delete, sender=TradeAcceptance)
|
||||
def bubble_up_trade_offer_updates(sender, instance, **kwargs):
|
||||
"""
|
||||
Bubble up updates to the TradeOffer model when TradeOfferHaveCard, TradeOfferWantCard,
|
||||
or TradeAcceptance instances are created, updated, or deleted.
|
||||
"""
|
||||
if instance.trade_offer:
|
||||
instance.trade_offer.save(update_fields=['updated_at'])
|
||||
|
|
@ -9,8 +9,10 @@ def render_trade_offer(context, offer):
|
|||
Renders a trade offer including detailed trade acceptance information.
|
||||
Freezes the through-model querysets to avoid extra DB hits.
|
||||
"""
|
||||
trade_offer_have_cards = list(offer.trade_offer_have_cards.all())
|
||||
trade_offer_want_cards = list(offer.trade_offer_want_cards.all())
|
||||
trade_offer_have_cards = list(offer.trade_offer_have_cards.select_related('card').all())
|
||||
trade_offer_want_cards = list(offer.trade_offer_want_cards.select_related('card').all())
|
||||
acceptances = list(offer.acceptances.select_related('accepted_by__user', 'requested_card', 'offered_card').all())
|
||||
|
||||
|
||||
have_cards_available = [
|
||||
card for card in trade_offer_have_cards
|
||||
|
|
@ -21,18 +23,14 @@ def render_trade_offer(context, offer):
|
|||
if card.quantity > card.qty_accepted
|
||||
]
|
||||
|
||||
acceptances = list(offer.acceptances.all())
|
||||
|
||||
# Determine if the offer should show its back side (acceptances view) by default.
|
||||
# If either side has no available cards, then flip the offer.
|
||||
if not have_cards_available or not want_cards_available:
|
||||
flipped = True
|
||||
else:
|
||||
flipped = False
|
||||
|
||||
return {
|
||||
tag_context = {
|
||||
'offer_pk': offer.pk,
|
||||
'flipped': flipped, # new flag to control the default face
|
||||
'flipped': flipped,
|
||||
'offer_hash': offer.hash,
|
||||
'rarity_icon': offer.rarity_icon,
|
||||
'initiated_by_email': offer.initiated_by.user.email,
|
||||
|
|
@ -43,19 +41,25 @@ def render_trade_offer(context, offer):
|
|||
'want_cards_available': want_cards_available,
|
||||
'num_cards_available': len(have_cards_available) + len(want_cards_available),
|
||||
'on_detail_page': context.get("request").path.endswith("trades/"+str(offer.pk)+"/"),
|
||||
'cache_key': f'trade_offer_{offer.pk}_{offer.updated_at.timestamp()}_{flipped}',
|
||||
}
|
||||
|
||||
context.update(tag_context)
|
||||
return context
|
||||
|
||||
@register.inclusion_tag('templatetags/trade_acceptance.html', takes_context=True)
|
||||
def render_trade_acceptance(context, acceptance):
|
||||
"""
|
||||
Renders a simple trade acceptance view with a single row and simplified header/footer.
|
||||
"""
|
||||
|
||||
return {
|
||||
tag_context = {
|
||||
"acceptance": acceptance,
|
||||
"request": context.get("request"),
|
||||
'cache_key': f'trade_acceptance_{acceptance.pk}_{acceptance.updated_at.timestamp()}',
|
||||
}
|
||||
|
||||
context.update(tag_context)
|
||||
return context
|
||||
|
||||
@register.filter
|
||||
def get_action_label(acceptance, state_value):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue