feat: improved product attribute views
CI / test (push) Successful in 1m51s
CI / build (push) Successful in 14s

This commit is contained in:
2026-07-27 12:55:11 +02:00
parent e02ee6b93a
commit 125c9dd186
4 changed files with 110 additions and 7 deletions
+30 -6
View File
@@ -306,14 +306,38 @@ class ProductImageDeleteView(BackofficeCRUDMixin, BackofficeModalDeleteMixin, De
# --- ProductVariant (nested under a product) ---
VARIANT_FORM_FRAGMENT = 'backoffice/products/_variant_form_fragment.html'
class ProductVariantCreateView(BackofficeCRUDMixin, BackofficeModalFormMixin, CreateView):
class ProductVariantAttributesContextMixin:
"""Agrupa los valores de atributo por atributo para pintarlos como tabla
(ver _variant_form_fragment.html) en vez del <ul> de checkboxes que genera
por defecto CheckboxSelectMultiple. Si el form viene con datos (reenvío
tras un error de validación, p.ej. combinación duplicada) se respeta lo
que el usuario había marcado en vez de lo que tuviera guardado la instancia."""
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
form = context['form']
if form.is_bound:
selected_value_ids = {int(v) for v in form.data.getlist('attribute_values') if v.isdigit()}
else:
instance = getattr(self, 'object', None)
selected_value_ids = set(instance.attribute_values.values_list('pk', flat=True)) if instance and instance.pk else set()
context['attributes'] = ProductAttribute.objects.prefetch_related('values')
context['selected_value_ids'] = selected_value_ids
return context
class ProductVariantCreateView(ProductVariantAttributesContextMixin, BackofficeCRUDMixin, BackofficeModalFormMixin, CreateView):
model = ProductVariant
form_class = ProductVariantForm
permission_required = 'shop.add_productvariant'
section = SECTION
template_name = 'backoffice/generic/form.html'
fragment_template_name = FORM_FRAGMENT
template_name = 'backoffice/products/variant_form.html'
fragment_template_name = VARIANT_FORM_FRAGMENT
def get_product(self):
return get_object_or_404(Product, pk=self.kwargs['product_pk'])
@@ -335,13 +359,13 @@ class ProductVariantCreateView(BackofficeCRUDMixin, BackofficeModalFormMixin, Cr
return reverse_lazy('backoffice:product_detail', args=[self.object.product_id])
class ProductVariantUpdateView(BackofficeCRUDMixin, BackofficeModalFormMixin, UpdateView):
class ProductVariantUpdateView(ProductVariantAttributesContextMixin, BackofficeCRUDMixin, BackofficeModalFormMixin, UpdateView):
model = ProductVariant
form_class = ProductVariantForm
permission_required = 'shop.change_productvariant'
section = SECTION
template_name = 'backoffice/generic/form.html'
fragment_template_name = FORM_FRAGMENT
template_name = 'backoffice/products/variant_form.html'
fragment_template_name = VARIANT_FORM_FRAGMENT
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)