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
30
theme/templatetags/_card_multiselect_options.html
Normal file
30
theme/templatetags/_card_multiselect_options.html
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{% load card_badge card_multiselect %}
|
||||
<option value="" disabled>{{ placeholder }}</option>
|
||||
{% for card in cards_to_render %}
|
||||
{% with card_id_str=card.pk|stringformat:"s" %} {# Ensure card PK is string for lookup #}
|
||||
{% if card_id_str in selected_cards %}
|
||||
<option
|
||||
value="{{ card.pk }}:{{ selected_cards|get_item:card_id_str }}"
|
||||
data-card-id="{{ card.pk }}"
|
||||
data-quantity="{{ selected_cards|get_item:card_id_str }}"
|
||||
selected
|
||||
data-html-content='<div class="m-2">{{ card|card_badge_inline:selected_cards|get_item:card_id_str }}</div>'
|
||||
data-name="{{ card.name }}"
|
||||
data-rarity="{{ card.rarity_icon }}"
|
||||
data-cardset="{{ card.cardset }}">
|
||||
{{ card.name }} {{ card.rarity_icon }} {{ card.cardset }}
|
||||
</option>
|
||||
{% else %}
|
||||
<option
|
||||
value="{{ card.pk }}:1"
|
||||
data-card-id="{{ card.pk }}"
|
||||
data-quantity="1"
|
||||
data-html-content='<div class="m-2">{{ card|card_badge_inline:"" }}</div>'
|
||||
data-name="{{ card.name }}"
|
||||
data-rarity="{{ card.rarity_icon }}"
|
||||
data-cardset="{{ card.cardset }}">
|
||||
{{ card.name }} {{ card.rarity_icon }} {{ card.cardset }}
|
||||
</option>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
|
@ -1,26 +1,29 @@
|
|||
<a href="{{ url }}" @click.stop>
|
||||
<div class="relative block">
|
||||
{% if not expanded %}
|
||||
<div class="flex flex-row items-center h-[32px] p-1.5 w-30 sm:w-40 text-white shadow-lg" style="{{ style }}">
|
||||
<div class="grow"><div class="truncate text-ellipsis font-semibold leading-tight text-sm marquee-calc w-4/5 sm:w-24">{{ name }}</div></div>
|
||||
<div class="grow-0 shrink-0 text-right truncate font-semibold leading-tight text-sm">{{ cardset }}</div>
|
||||
{% if quantity != None %}
|
||||
<div class="grow-0 shrink-0 relative w-fit ps-1">
|
||||
<div class="card-quantity-badge relative bg-gray-600 text-white text-sm font-semibold rounded-full text-center size-max px-1.5">{{ quantity }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="grid grid-rows-2 grid-cols-4 h-[52px] p-1.5 w-30 sm:w-40 text-white shadow-lg" style="{{ style }}">
|
||||
<div class="row-start-1 col-start-1 {% if quantity != None %}col-span-3{% else %}col-span-4{% endif %} self-start leading-tight truncate text-ellipsis"><span class="font-semibold text-sm marquee-calc">{{ name }}</span></div>
|
||||
{% if quantity != None %}
|
||||
<div class="row-start-1 col-start-4 col-span-1 self-start ms-auto leading-tight relative w-fit ps-1">
|
||||
<div class="card-quantity-badge relative bg-gray-600 text-white text-sm font-semibold rounded-full text-center size-max px-1.5">{{ quantity }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row-start-2 col-start-1 col-span-3 truncate self-end text-xs text-transparent">{{ rarity }}</div>
|
||||
<div class="row-start-2 col-start-4 col-span-1 self-end text-right truncate font-semibold leading-tight text-sm">{{ cardset }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
{% load cache %}
|
||||
{% cache CACHE_TIMEOUT card_badge cache_key %}
|
||||
<a href="{{ url }}" @click.stop>
|
||||
<div class="relative block">
|
||||
{% if not expanded %}
|
||||
<div class="flex flex-row items-center h-[32px] p-1.5 w-30 sm:w-40 text-white shadow-lg" style="{{ style }}">
|
||||
<div class="grow"><div class="truncate text-ellipsis font-semibold leading-tight text-sm marquee-calc w-4/5 sm:w-24">{{ name }}</div></div>
|
||||
<div class="grow-0 shrink-0 text-right truncate font-semibold leading-tight text-sm">{{ cardset }}</div>
|
||||
{% if quantity != None %}
|
||||
<div class="grow-0 shrink-0 relative w-fit ps-1">
|
||||
<div class="card-quantity-badge relative bg-gray-600 text-white text-sm font-semibold rounded-full text-center size-max px-1.5">{{ quantity }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="grid grid-rows-2 grid-cols-4 h-[52px] p-1.5 w-30 sm:w-40 text-white shadow-lg" style="{{ style }}">
|
||||
<div class="row-start-1 col-start-1 {% if quantity != None %}col-span-3{% else %}col-span-4{% endif %} self-start leading-tight truncate text-ellipsis"><span class="font-semibold text-sm marquee-calc">{{ name }}</span></div>
|
||||
{% if quantity != None %}
|
||||
<div class="row-start-1 col-start-4 col-span-1 self-start ms-auto leading-tight relative w-fit ps-1">
|
||||
<div class="card-quantity-badge relative bg-gray-600 text-white text-sm font-semibold rounded-full text-center size-max px-1.5">{{ quantity }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row-start-2 col-start-1 col-span-3 truncate self-end text-xs text-transparent">{{ rarity }}</div>
|
||||
<div class="row-start-2 col-start-4 col-span-1 self-end text-right truncate font-semibold leading-tight text-sm">{{ cardset }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
{% endcache %}
|
||||
|
|
@ -1,22 +1,16 @@
|
|||
{% load cache card_badge %}
|
||||
{% load cache card_multiselect %}
|
||||
|
||||
<label for="{{ field_id }}" class="label">
|
||||
<span class="label-text">{{ label }}</span>
|
||||
</label>
|
||||
<select name="{{ field_name }}" id="{{ field_id }}" class="select select-bordered w-full card-multiselect" data-placeholder="{{ placeholder }}" multiple x-cloak>
|
||||
{% cache cache_timeout card_multiselect selected_values|join:"," %}
|
||||
<option value="" disabled>{{ placeholder }}</option>
|
||||
{% for card in cards %}
|
||||
<option
|
||||
value="{{ card.pk }}"
|
||||
data-card-id="{{ card.pk }}"
|
||||
data-quantity="{{ card.selected_quantity }}"
|
||||
{% if card.selected %}selected{% endif %}
|
||||
data-html-content='<div class="m-2">{{ card|card_badge_inline:"__QUANTITY__" }}</div>'
|
||||
data-name="{{ card.name }}"
|
||||
data-rarity="{{ card.rarity_icon }}"
|
||||
data-cardset="{{ card.cardset }}">
|
||||
{{ card.name }} {{ card.rarity_icon }} {{ card.cardset }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
{% cache CACHE_TIMEOUT card_multiselect field_name label placeholder passed_cards_identifier selected_cards_key_part %}
|
||||
{% if has_passed_cards %}
|
||||
{% include "templatetags/_card_multiselect_options.html" with cards_to_render=passed_cards selected_cards=selected_cards placeholder=placeholder %}
|
||||
{% else %}
|
||||
{% fetch_all_cards as all_db_cards %}
|
||||
{% include "templatetags/_card_multiselect_options.html" with cards_to_render=all_db_cards selected_cards=selected_cards placeholder=placeholder %}
|
||||
{% endif %}
|
||||
{% endcache %}
|
||||
</select>
|
||||
|
|
@ -1,58 +1,60 @@
|
|||
{% load gravatar card_badge %}
|
||||
|
||||
<div class="card card-border bg-base-100 shadow-lg max-w-90 mx-auto">
|
||||
<!-- Header -->
|
||||
<a href="{% url 'trade_acceptance_update' pk=acceptance.pk %}">
|
||||
<div class="my-4 mx-4">
|
||||
<div class="flex justify-start items-center">
|
||||
<!-- Left: Initiator's avatar and "Has" -->
|
||||
<div class="flex items-center">
|
||||
<div class="avatar me-2 tooltip tooltip-top cursor-default" @click.stop.prevent data-tip="{{ acceptance.trade_offer.initiated_by.user.username }} | {{ acceptance.trade_offer.initiated_by.user.reputation_score }} rep">
|
||||
<div class="max-w-10 rounded-full">
|
||||
{{ acceptance.trade_offer.initiated_by.user.email|gravatar:40 }}
|
||||
{% cache CACHE_TIMEOUT trade_acceptance cache_key %}
|
||||
<div class="card card-border bg-base-100 shadow-lg max-w-90 mx-auto">
|
||||
<!-- Header -->
|
||||
<a href="{% url 'trade_acceptance_update' pk=acceptance.pk %}">
|
||||
<div class="my-4 mx-4">
|
||||
<div class="flex justify-start items-center">
|
||||
<!-- Left: Initiator's avatar and "Has" -->
|
||||
<div class="flex items-center">
|
||||
<div class="avatar me-2 tooltip tooltip-top cursor-default" @click.stop.prevent data-tip="{{ acceptance.trade_offer.initiated_by.user.username }} | {{ acceptance.trade_offer.initiated_by.user.reputation_score }} rep">
|
||||
<div class="max-w-10 rounded-full">
|
||||
{{ acceptance.trade_offer.initiated_by.user.email|gravatar:40 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-gray-500 text-xs">
|
||||
{% if acceptance.is_initiator_state %}
|
||||
{{ acceptance.action_label_2 }}
|
||||
{% else %}
|
||||
Waiting on {{ acceptance.trade_offer.initiated_by.user.username }} to {{ acceptance.next_action_label }}...
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<!-- Main Card Row: Single row with the acceptance's cards -->
|
||||
<div class="px-2 pb-0">
|
||||
<div class="grid grid-cols-2 items-center gap-2">
|
||||
<div class="flex flex-col items-center">
|
||||
{% card_badge acceptance.requested_card %}
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
{% card_badge acceptance.offered_card %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{% url 'trade_acceptance_update' pk=acceptance.pk %}">
|
||||
<div class="my-4 mx-4">
|
||||
<div class="flex justify-end items-center">
|
||||
<!-- Right: "Wants" with the acceptor's avatar -->
|
||||
<div class="flex items-center">
|
||||
<div class="text-gray-500 text-xs text-right">
|
||||
{% if acceptance.is_acceptor_state %}
|
||||
{{ acceptance.action_label_2 }}
|
||||
{% else %}
|
||||
Waiting on {{ acceptance.accepted_by.user.username }} to {{ acceptance.next_action_label }}...
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="avatar ms-2 tooltip tooltip-bottom cursor-default" @click.stop.prevent data-tip="{{ acceptance.accepted_by.user.username}} | {{ acceptance.accepted_by.user.reputation_score }} rep">
|
||||
<div class="max-w-10 rounded-full">
|
||||
{{ acceptance.accepted_by.user.email|gravatar:40 }}
|
||||
<div class="text-gray-500 text-xs">
|
||||
{% if acceptance.is_initiator_state %}
|
||||
{{ acceptance.action_label_2 }}
|
||||
{% else %}
|
||||
Waiting on {{ acceptance.trade_offer.initiated_by.user.username }} to {{ acceptance.next_action_label }}...
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<!-- Main Card Row: Single row with the acceptance's cards -->
|
||||
<div class="px-2 pb-0">
|
||||
<div class="grid grid-cols-2 items-center gap-2">
|
||||
<div class="flex flex-col items-center">
|
||||
{% card_badge acceptance.requested_card %}
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
{% card_badge acceptance.offered_card %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<a href="{% url 'trade_acceptance_update' pk=acceptance.pk %}">
|
||||
<div class="my-4 mx-4">
|
||||
<div class="flex justify-end items-center">
|
||||
<!-- Right: "Wants" with the acceptor's avatar -->
|
||||
<div class="flex items-center">
|
||||
<div class="text-gray-500 text-xs text-right">
|
||||
{% if acceptance.is_acceptor_state %}
|
||||
{{ acceptance.action_label_2 }}
|
||||
{% else %}
|
||||
Waiting on {{ acceptance.accepted_by.user.username }} to {{ acceptance.next_action_label }}...
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="avatar ms-2 tooltip tooltip-bottom cursor-default" @click.stop.prevent data-tip="{{ acceptance.accepted_by.user.username}} | {{ acceptance.accepted_by.user.reputation_score }} rep">
|
||||
<div class="max-w-10 rounded-full">
|
||||
{{ acceptance.accepted_by.user.email|gravatar:40 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{% endcache %}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{% load gravatar card_badge cache %}
|
||||
|
||||
{% cache 60 trade_offer offer_pk %}
|
||||
{% cache CACHE_TIMEOUT trade_offer cache_key %}
|
||||
<div x-data="{ flipped: {{flipped|lower}}, offerExpanded: {{flipped|yesno:'false,true'}}, acceptanceExpanded: {{flipped|lower}} }" x-ref="tradeOffer" class="transition-all duration-500 trade-offer-card">
|
||||
<div class="flip-container">
|
||||
<div class="flip-inner grid grid-cols-1 grid-rows-1 card bg-base-100 card-border shadow-lg w-90 transform transition-transform duration-500 ease-in-out{%if flipped %} rotate-y-180{% endif %}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue