product create fix error
This commit is contained in:
2
core/apps/vendors/models/product_variant.py
vendored
2
core/apps/vendors/models/product_variant.py
vendored
@@ -3,6 +3,8 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from django_core.models import AbstractBaseModel
|
from django_core.models import AbstractBaseModel
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProductVariantModel(AbstractBaseModel):
|
class ProductVariantModel(AbstractBaseModel):
|
||||||
product = models.ForeignKey(
|
product = models.ForeignKey(
|
||||||
"VendorproductModel",
|
"VendorproductModel",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from core.apps.vendors.models import (
|
from core.apps.vendors.models import (
|
||||||
@@ -151,14 +152,63 @@ class CreateVendorproductSerializer(BaseVendorproductSerializer):
|
|||||||
write_only=True,
|
write_only=True,
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
variants = ProductVariantSerializer(many=True, required=False)
|
||||||
|
|
||||||
class Meta(BaseVendorproductSerializer.Meta):
|
class Meta(BaseVendorproductSerializer.Meta):
|
||||||
fields = BaseVendorproductSerializer.Meta.fields + [
|
fields = BaseVendorproductSerializer.Meta.fields + [
|
||||||
"uploaded_images",
|
"uploaded_images",
|
||||||
|
"variants",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
# form-data kelsa QueryDict bo'ladi
|
||||||
|
# getlist() bilan bir xil kalit uchun barcha qiymatlarni olamiz, keyin dict'ga o'tkazamiz
|
||||||
|
if hasattr(data, "getlist"):
|
||||||
|
multi_images = data.getlist("uploaded_images")
|
||||||
|
data = data.dict()
|
||||||
|
if multi_images:
|
||||||
|
data["uploaded_images"] = multi_images
|
||||||
|
|
||||||
|
# uploaded_images ichida URL string kelsa — ularni photos_json ga ko'chiramiz,
|
||||||
|
# haqiqiy fayllarni uploaded_images da qoldiramiz
|
||||||
|
raw_images = data.get("uploaded_images")
|
||||||
|
if raw_images:
|
||||||
|
if isinstance(raw_images, str):
|
||||||
|
try:
|
||||||
|
raw_images = json.loads(raw_images)
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
raw_images = [raw_images]
|
||||||
|
|
||||||
|
if isinstance(raw_images, list):
|
||||||
|
url_list = [v for v in raw_images if isinstance(v, str)]
|
||||||
|
file_list = [v for v in raw_images if not isinstance(v, str)]
|
||||||
|
|
||||||
|
if url_list:
|
||||||
|
existing = data.get("photos_json") or []
|
||||||
|
if isinstance(existing, str):
|
||||||
|
try:
|
||||||
|
existing = json.loads(existing)
|
||||||
|
except Exception:
|
||||||
|
existing = []
|
||||||
|
data["photos_json"] = existing + url_list
|
||||||
|
|
||||||
|
data["uploaded_images"] = file_list if file_list else []
|
||||||
|
|
||||||
|
json_fields = ["variants", "product_specification", "photos_json"]
|
||||||
|
for field in json_fields:
|
||||||
|
value = data.get(field)
|
||||||
|
if value and isinstance(value, str):
|
||||||
|
try:
|
||||||
|
data[field] = json.loads(value)
|
||||||
|
except (json.JSONDecodeError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
return super().to_internal_value(data)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
uploaded_images = validated_data.pop("uploaded_images", [])
|
uploaded_images = validated_data.pop("uploaded_images", [])
|
||||||
|
variants_data = validated_data.pop("variants", [])
|
||||||
|
|
||||||
instance = super().create(validated_data)
|
instance = super().create(validated_data)
|
||||||
|
|
||||||
# Save additional gallery images
|
# Save additional gallery images
|
||||||
@@ -168,19 +218,52 @@ class CreateVendorproductSerializer(BaseVendorproductSerializer):
|
|||||||
image=img,
|
image=img,
|
||||||
order=i
|
order=i
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Save variants
|
||||||
|
for variant_data in variants_data:
|
||||||
|
ProductVariantModel.objects.create(
|
||||||
|
product=instance,
|
||||||
|
**variant_data
|
||||||
|
)
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
uploaded_images = validated_data.pop("uploaded_images", [])
|
uploaded_images = validated_data.pop("uploaded_images", [])
|
||||||
|
variants_data = validated_data.pop("variants", None)
|
||||||
|
|
||||||
instance = super().update(instance, validated_data)
|
instance = super().update(instance, validated_data)
|
||||||
|
|
||||||
if uploaded_images:
|
if uploaded_images:
|
||||||
# Optionally clear existing gallery or append?
|
|
||||||
# I'll append for now based on user's "how to upload multiple"
|
|
||||||
for i, img in enumerate(uploaded_images):
|
for i, img in enumerate(uploaded_images):
|
||||||
ProductimageModel.objects.create(
|
ProductimageModel.objects.create(
|
||||||
product=instance,
|
product=instance,
|
||||||
image=img,
|
image=img,
|
||||||
order=instance.images.count() + i
|
order=instance.images.count() + i
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if variants_data is not None:
|
||||||
|
# Simple approach: clear and recreation or matching by firestore_id/SKU
|
||||||
|
# For now, I'll update variants if they have an ID or firestore_id, otherwise create
|
||||||
|
|
||||||
|
# To keep it robust, let's track current variants
|
||||||
|
current_variants = {v.firestore_id: v for v in instance.variants.all() if v.firestore_id}
|
||||||
|
|
||||||
|
new_variants = []
|
||||||
|
for v_data in variants_data:
|
||||||
|
v_fid = v_data.get("firestore_id")
|
||||||
|
if v_fid and v_fid in current_variants:
|
||||||
|
# Update existing
|
||||||
|
v_instance = current_variants.pop(v_fid)
|
||||||
|
for attr, value in v_data.items():
|
||||||
|
setattr(v_instance, attr, value)
|
||||||
|
v_instance.save()
|
||||||
|
else:
|
||||||
|
# Create new
|
||||||
|
ProductVariantModel.objects.create(product=instance, **v_data)
|
||||||
|
|
||||||
|
# Optional: delete variants that are not in the new data
|
||||||
|
# for v in current_variants.values():
|
||||||
|
# v.delete()
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|||||||
Reference in New Issue
Block a user