[WIP] trying formset attempt

main
mtyton 2023-07-16 16:22:09 +02:00
rodzic c76e6fbc12
commit c7aa69448c
6 zmienionych plików z 144 dodań i 33 usunięć

Wyświetl plik

@ -40,12 +40,10 @@ class OutgoingMailAdmin(ModelAdmin):
exclude_from_explorer = False
list_display = (
"subject",
"to",
"sent",
)
search_fields = (
"subject",
"to",
)
list_filter = (
"subject",

Wyświetl plik

@ -40,26 +40,39 @@ class CustomerDataForm(forms.Form):
)
class ProductCategoryParamForm(forms.ModelForm):
class ProductCategoryParamFormset(forms.BaseModelFormSet):
...
class ProductCategoryParamValueForm(forms.ModelForm):
class Meta:
model = ProductCategoryParam
model = ProductCategoryParamValue
fields = ("key", "value")
readonly_fields = ("key", )
def __init__(self, instance, *args, **kwargs):
super().__init__(*args, instance=instance, **kwargs)
self.fields["key"].widget.attrs["disabled"] = True
self.fields["value"].choices = [
(param_value.pk, param_value.value) for param_value in instance.param_values.all()
]
key = forms.CharField(required=True)
value = forms.ModelChoiceField(
queryset=ProductCategoryParamValue.objects.none(),
widget=forms.RadioSelect(attrs={"class": "form-control"})
widget=forms.RadioSelect(attrs={"class": "btn-check", "type": "radio", "autocomplete": "off"}),
required=True
)
def _get_instace(self, key: str):
return ProductCategoryParam.objects.get(key=key)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
key = self.initial.get("key")
if not key:
return
self.cat_param = self._get_instace(key)
self.fields["value"].choices = [
(param_value.pk, param_value.value) for param_value in self.cat_param.param_values.all()
]
def save(self, *args, **kwargs):
return ProductCategoryParamValue.objects.get(
param=self.instance,
param_value = ProductCategoryParamValue.objects.get(
param__key=str(self.cleaned_data["key"]),
value=str(self.cleaned_data["value"])
)
print(param_value or "DUPSKo")
return param_value

Wyświetl plik

@ -171,12 +171,22 @@ class ProductTemplateImage(BaseImageModel):
class ProductManager(models.Manager):
def get_or_create_by_params(self, params: list[ProductCategoryParamValue], template: ProductTemplate):
product = self.filter(params__in=params).first()
products = self.filter(template=template)
# TODO - other price
price_proposal = products.first().price if products.first() else 4.0
for param in params:
products = products.filter(params__pk=param.pk)
# There should be only one
if not products.count() <= 1:
raise ValidationError("There should be only one product with given set of params")
product = products.first()
if not product:
product = self.create(
name=f"{template.title} - AUTOGENERATED",
template=template,
price=...,
price=price_proposal,
available=False
)
for param in params:
@ -194,6 +204,8 @@ class Product(ClusterableModel):
price = models.FloatField()
available = models.BooleanField(default=True)
objects = ProductManager()
panels = [
FieldPanel("template"),
FieldPanel("price"),

Wyświetl plik

@ -23,16 +23,21 @@
<div class="container">
<form action="" method="POST" class="mt-5">
{% csrf_token %}
{{ formset.management_form }}
<div class="row mt-5">
{% for form in forms %}
{% for form in formset.forms %}
<div class="col-6 text-center">
<h3>{{form.instance}}</h3>
{% for value, label in form.value.field.choices %}
<div class="btn-group btn-group-toggle" role="group">
<input type="radio" class="btn-check" name="{{form.key.value}}" id="{{value}}" autocomplete="off" checked>
<label class="btn btn-outline-primary" for="{{value}}">{{label}}</label>
</div>
{% endfor %}
<h3>{{form.cat_param}}</h3>
{% if form.value.field.choices %}
<input type="hidden" name="{{form.prefix}}-key" value="{{form.key.value}}">
{% for value, label in form.value.field.choices %}
<div class="btn-group btn-group-toggle" role="group">
<input type="radio" class="btn-check" name="{{form.prefix}}-value" id="{{value}}" autocomplete="off" value="{{value}}" required>
<label class="btn btn-outline-primary" for="{{value}}">{{label}}</label>
</div>
{% endfor %}
{% endif %}
</div>
{% if forloop.counter|divisibleby:"2" %} </div><div class="row mt-5">{% endif %}
{% endfor %}

Wyświetl plik

@ -98,6 +98,48 @@ class ProductTestCase(TestCase):
product.params.add(sec_param_value)
self.assertEqual(product.params.count(), 0)
def test_get_or_create_by_params_success(self):
product = factories.ProductFactory(available=True)
value1 = factories.ProductCategoryParamValueFactory()
value2 = factories.ProductCategoryParamValueFactory()
product.params.add(value1)
product.params.add(value2)
product.save()
prod = store_models.Product.objects.get_or_create_by_params(
params=[value1, value2], template=product.template,
)
self.assertIsNotNone(prod)
self.assertEqual(prod.pk, product.pk)
self.assertTrue(prod.available)
def test_get_or_create_by_params_success_not_existing_product(self):
product = factories.ProductFactory(available=True)
value1 = factories.ProductCategoryParamValueFactory()
value2 = factories.ProductCategoryParamValueFactory()
product.params.add(value1)
product.price = 13.0
product.save()
prod = store_models.Product.objects.get_or_create_by_params(
params=[value1, value2], template=product.template,
)
self.assertIsNotNone(prod)
self.assertNotEqual(prod.pk, product.pk)
self.assertFalse(prod.available)
self.assertEqual(prod.price, 13.0)
def test_get_or_create_by_params_success_not_existing_product_no_other_products(self):
template = factories.ProductTemplateFactory()
value1 = factories.ProductCategoryParamValueFactory()
value2 = factories.ProductCategoryParamValueFactory()
prod = store_models.Product.objects.get_or_create_by_params(
params=[value1, value2], template=template,
)
self.assertIsNotNone(prod)
self.assertFalse(prod.available)
self.assertEqual(prod.price, 4.0)
class OrderProductTestCase(TestCase):
def setUp(self):

Wyświetl plik

@ -8,6 +8,7 @@ from django.shortcuts import render
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.forms import modelformset_factory
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
@ -19,12 +20,14 @@ from store.serializers import (
)
from store.forms import (
CustomerDataForm,
ProductCategoryParamForm
ProductCategoryParamValueForm,
ProductCategoryParamFormset
)
from store.models import (
Order,
Product,
ProductTemplate
ProductTemplate,
ProductCategoryParamValue
)
@ -96,13 +99,17 @@ class ConfigureProductView(View):
def get_context_data(self, pk: int, **kwargs: Any) -> Dict[str, Any]:
template = ProductTemplate.objects.get(pk=pk)
category_params = template.category.category_params.all()
formset_class = modelformset_factory(
ProductCategoryParamValue,
form=ProductCategoryParamValueForm,
formset=ProductCategoryParamFormset
)
formset = formset_class(queryset=category_params)
context = {
"template": template,
"available_variants": Product.objects.filter(template__pk=pk),
"category_params": category_params,
"forms": [ProductCategoryParamForm(instance=param) for param in category_params]
"formset": formset
}
return context
@ -112,8 +119,42 @@ class ConfigureProductView(View):
return render(request, self.template_name, context)
def post(self, request, pk: int, *args, **kwargs):
# first select template
template = ProductTemplate.objects.get(pk=pk)
category_params = template.category.category_params.all()
params_values = []
formset_class = modelformset_factory(
ProductCategoryParamValue,
form=ProductCategoryParamValueForm,
formset=ProductCategoryParamFormset
)
formset = formset_class(queryset=category_params, data=request.POST)
print(request.POST)
return HttpResponseRedirect(reverse("product-configure-summary", kwargs={"variant_pk": 1}))
if not formset.is_valid():
print(formset.errors)
messages.error(request, "Niepoprawne dane")
context = self.get_context_data(pk)
context["formset"] = formset
return render(request, self.template_name, context)
for form in formset.forms:
if not form.is_valid():
messages.error(request, "Niepoprawne dane")
context = self.get_context_data(pk)
context["formset"] = formset
return render(request, self.template_name, context)
params_values.append(form.save())
product_variant = Product.objects.get_or_create_by_params(
template=ProductTemplate.objects.get(pk=pk), params=params_values
)
if not product_variant:
messages.error(request, "Nie udało się utworzyć wariantu produktu")
return HttpResponseRedirect(reverse("product-configure", kwargs={"pk": pk}))
return HttpResponseRedirect(
reverse("product-configure-summary", kwargs={"variant_pk": product_variant.pk})
)
class ConfigureProductSummaryView(View):
@ -123,7 +164,7 @@ class ConfigureProductSummaryView(View):
variant = Product.objects.get(pk=variant_pk)
context = {
"variant": variant,
"category_params": variant.template.category.category_params.all()
"params_values": variant.params.all()
}
return render(request, self.template_name, context)