categorylanri import qilish qoshildi
This commit is contained in:
9
core/apps/vendors/admin/category.py
vendored
9
core/apps/vendors/admin/category.py
vendored
@@ -8,6 +8,13 @@ from core.apps.vendors.models import CategoryModel
|
||||
class CategoryAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"__str__",
|
||||
"title",
|
||||
"section",
|
||||
"photo",
|
||||
"photo_url",
|
||||
"is_publish",
|
||||
"order",
|
||||
)
|
||||
search_fields = ("title", "firestore_id")
|
||||
list_filter = ("section", "is_publish")
|
||||
|
||||
|
||||
17
core/apps/vendors/admin/vendor_product.py
vendored
17
core/apps/vendors/admin/vendor_product.py
vendored
@@ -8,13 +8,26 @@ from core.apps.vendors.models import ProductimageModel, VendorproductModel
|
||||
class VendorproductAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"__str__",
|
||||
"name",
|
||||
"vendor",
|
||||
"category",
|
||||
"section",
|
||||
"price",
|
||||
"quantity",
|
||||
"is_publish",
|
||||
"image",
|
||||
)
|
||||
search_fields = ("name", "firestore_id", "vendor")
|
||||
list_filter = ("is_publish", "category", "section")
|
||||
autocomplete_fields = ("category", "section")
|
||||
|
||||
|
||||
@admin.register(ProductimageModel)
|
||||
class ProductimageAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"__str__",
|
||||
"product",
|
||||
"image",
|
||||
"order",
|
||||
)
|
||||
list_filter = ("product",)
|
||||
|
||||
@@ -19,23 +19,58 @@ class BaseCategorySerializer(serializers.ModelSerializer):
|
||||
"is_publish",
|
||||
"order",
|
||||
]
|
||||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
request = self.context.get("request")
|
||||
|
||||
photo_url = ret.get("photo_url")
|
||||
if photo_url and isinstance(photo_url, str):
|
||||
if not photo_url.startswith("http"):
|
||||
path = f"/resources/media/{photo_url.lstrip('/')}"
|
||||
if request:
|
||||
ret["photo_url"] = request.build_absolute_uri(path)
|
||||
else:
|
||||
ret["photo_url"] = path
|
||||
elif "localhost" in photo_url and request and "localhost" not in request.get_host():
|
||||
path = photo_url.split("/resources/media/")[-1]
|
||||
ret["photo_url"] = request.build_absolute_uri(f"/resources/media/{path}")
|
||||
|
||||
# Fallback for main photo if it's null
|
||||
if not ret.get("photo") and ret.get("photo_url"):
|
||||
ret["photo"] = ret["photo_url"]
|
||||
|
||||
# Ensure main photo is absolute if it's a relative path
|
||||
photo = ret.get("photo")
|
||||
if photo and isinstance(photo, str) and not photo.startswith("http"):
|
||||
if not photo.startswith("/resources/"):
|
||||
photo = f"/resources/media/{photo.lstrip('/')}"
|
||||
|
||||
if request:
|
||||
ret["photo"] = request.build_absolute_uri(photo)
|
||||
else:
|
||||
ret["photo"] = photo
|
||||
|
||||
return ret
|
||||
|
||||
class ListCategorySerializer(BaseCategorySerializer):
|
||||
class Meta(BaseCategorySerializer.Meta): ...
|
||||
class Meta(BaseCategorySerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
class RetrieveCategorySerializer(BaseCategorySerializer):
|
||||
class Meta(BaseCategorySerializer.Meta): ...
|
||||
class Meta(BaseCategorySerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
class CreateCategorySerializer(BaseCategorySerializer):
|
||||
class Meta(BaseCategorySerializer.Meta):
|
||||
fields = [
|
||||
"id",
|
||||
"firestore_id",
|
||||
"section",
|
||||
"title",
|
||||
"description",
|
||||
"photo",
|
||||
"photo_url",
|
||||
"is_publish",
|
||||
"order",
|
||||
|
||||
33
core/apps/vendors/serializers/section/Section.py
vendored
33
core/apps/vendors/serializers/section/Section.py
vendored
@@ -15,6 +15,39 @@ class BaseSectionSerializer(serializers.ModelSerializer):
|
||||
"service_type",
|
||||
]
|
||||
|
||||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
request = self.context.get("request")
|
||||
|
||||
image_url = ret.get("image_url")
|
||||
if image_url and isinstance(image_url, str):
|
||||
if not image_url.startswith("http"):
|
||||
path = f"/resources/media/{image_url.lstrip('/')}"
|
||||
if request:
|
||||
ret["image_url"] = request.build_absolute_uri(path)
|
||||
else:
|
||||
ret["image_url"] = path
|
||||
elif "localhost" in image_url and request and "localhost" not in request.get_host():
|
||||
path = image_url.split("/resources/media/")[-1]
|
||||
ret["image_url"] = request.build_absolute_uri(f"/resources/media/{path}")
|
||||
|
||||
# Fallback for main image if it's null
|
||||
if not ret.get("image") and ret.get("image_url"):
|
||||
ret["image"] = ret["image_url"]
|
||||
|
||||
# Ensure main image is absolute if it's a relative path
|
||||
image = ret.get("image")
|
||||
if image and isinstance(image, str) and not image.startswith("http"):
|
||||
if not image.startswith("/resources/"):
|
||||
image = f"/resources/media/{image.lstrip('/')}"
|
||||
|
||||
if request:
|
||||
ret["image"] = request.build_absolute_uri(image)
|
||||
else:
|
||||
ret["image"] = image
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
class ListSectionSerializer(BaseSectionSerializer):
|
||||
pass
|
||||
|
||||
39
core/apps/vendors/serializers/vendor/vendor.py
vendored
39
core/apps/vendors/serializers/vendor/vendor.py
vendored
@@ -20,25 +20,60 @@ class BaseVendorSerializer(serializers.ModelSerializer):
|
||||
"photo_url",
|
||||
"is_active",
|
||||
]
|
||||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
request = self.context.get("request")
|
||||
|
||||
photo_url = ret.get("photo_url")
|
||||
if photo_url and isinstance(photo_url, str):
|
||||
if not photo_url.startswith("http"):
|
||||
path = f"/resources/media/{photo_url.lstrip('/')}"
|
||||
if request:
|
||||
ret["photo_url"] = request.build_absolute_uri(path)
|
||||
else:
|
||||
ret["photo_url"] = path
|
||||
elif "localhost" in photo_url and request and "localhost" not in request.get_host():
|
||||
path = photo_url.split("/resources/media/")[-1]
|
||||
ret["photo_url"] = request.build_absolute_uri(f"/resources/media/{path}")
|
||||
|
||||
# Fallback for main photo if it's null
|
||||
if not ret.get("photo") and ret.get("photo_url"):
|
||||
ret["photo"] = ret["photo_url"]
|
||||
|
||||
# Ensure main photo is absolute if it's a relative path
|
||||
photo = ret.get("photo")
|
||||
if photo and isinstance(photo, str) and not photo.startswith("http"):
|
||||
if not photo.startswith("/resources/"):
|
||||
photo = f"/resources/media/{photo.lstrip('/')}"
|
||||
|
||||
if request:
|
||||
ret["photo"] = request.build_absolute_uri(photo)
|
||||
else:
|
||||
ret["photo"] = photo
|
||||
|
||||
return ret
|
||||
|
||||
class ListVendorSerializer(BaseVendorSerializer):
|
||||
class Meta(BaseVendorSerializer.Meta): ...
|
||||
class Meta(BaseVendorSerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
class RetrieveVendorSerializer(BaseVendorSerializer):
|
||||
class Meta(BaseVendorSerializer.Meta): ...
|
||||
class Meta(BaseVendorSerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
class CreateVendorSerializer(BaseVendorSerializer):
|
||||
class Meta(BaseVendorSerializer.Meta):
|
||||
fields = [
|
||||
"id",
|
||||
"firestore_id",
|
||||
"section",
|
||||
"title",
|
||||
"description",
|
||||
"phone",
|
||||
"location",
|
||||
"photo",
|
||||
"photo_url",
|
||||
"is_active",
|
||||
]
|
||||
|
||||
@@ -8,7 +8,9 @@ class BaseProductimageSerializer(serializers.ModelSerializer):
|
||||
model = ProductimageModel
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"product",
|
||||
"image",
|
||||
"order",
|
||||
]
|
||||
|
||||
|
||||
@@ -23,6 +25,7 @@ class RetrieveProductimageSerializer(BaseProductimageSerializer):
|
||||
class CreateProductimageSerializer(BaseProductimageSerializer):
|
||||
class Meta(BaseProductimageSerializer.Meta):
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"product",
|
||||
"image",
|
||||
"order",
|
||||
]
|
||||
|
||||
@@ -3,9 +3,13 @@ from rest_framework import serializers
|
||||
from core.apps.vendors.models import VendorproductModel, VendorModel, CategoryModel, SectionModel
|
||||
|
||||
|
||||
from core.apps.vendors.serializers.vendor_product.ProductImage import ListProductimageSerializer
|
||||
|
||||
|
||||
class BaseVendorproductSerializer(serializers.ModelSerializer):
|
||||
category = serializers.SlugRelatedField(slug_field='firestore_id', queryset=CategoryModel.objects.all(), required=False, allow_null=True)
|
||||
section = serializers.SlugRelatedField(slug_field='firestore_id', queryset=SectionModel.objects.all(), required=False, allow_null=True)
|
||||
images = ListProductimageSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = VendorproductModel
|
||||
@@ -22,30 +26,106 @@ class BaseVendorproductSerializer(serializers.ModelSerializer):
|
||||
"quantity",
|
||||
"is_publish",
|
||||
"image",
|
||||
"images",
|
||||
"photos_json",
|
||||
]
|
||||
|
||||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
request = self.context.get("request")
|
||||
photos = ret.get("photos_json")
|
||||
|
||||
# Handle photos_json list
|
||||
processed_photos = []
|
||||
if photos and isinstance(photos, list):
|
||||
for photo in photos:
|
||||
if isinstance(photo, str):
|
||||
# Agar URL to'liq bo'lmasa yoki localhost bo'lsa, uni dinamik qilamiz
|
||||
if not photo.startswith("http"):
|
||||
path = f"/resources/media/{photo}"
|
||||
if request:
|
||||
processed_photos.append(request.build_absolute_uri(path))
|
||||
else:
|
||||
processed_photos.append(path)
|
||||
elif "localhost" in photo and request and "localhost" not in request.get_host():
|
||||
# Agar bazada localhost saqlangan bo'lsa-yu, biz boshqa domenda bo'lsak
|
||||
path = photo.split("/resources/media/")[-1]
|
||||
processed_photos.append(request.build_absolute_uri(f"/resources/media/{path}"))
|
||||
else:
|
||||
processed_photos.append(photo)
|
||||
else:
|
||||
processed_photos.append(photo)
|
||||
|
||||
ret["photos_json"] = processed_photos
|
||||
|
||||
# Fallback for main image if it's null
|
||||
if not ret.get("image") and processed_photos:
|
||||
ret["image"] = processed_photos[0]
|
||||
|
||||
# Ensure main image is absolute if it's a relative path (fallback for custom storage)
|
||||
image = ret.get("image")
|
||||
if image and isinstance(image, str) and not image.startswith("http"):
|
||||
# Check if it already has resources prefix
|
||||
if not image.startswith("/resources/"):
|
||||
image = f"/resources/media/{image.lstrip('/')}"
|
||||
|
||||
if request:
|
||||
ret["image"] = request.build_absolute_uri(image)
|
||||
else:
|
||||
ret["image"] = image
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
|
||||
class ListVendorproductSerializer(BaseVendorproductSerializer):
|
||||
class Meta(BaseVendorproductSerializer.Meta): ...
|
||||
class Meta(BaseVendorproductSerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
class RetrieveVendorproductSerializer(BaseVendorproductSerializer):
|
||||
class Meta(BaseVendorproductSerializer.Meta): ...
|
||||
class Meta(BaseVendorproductSerializer.Meta):
|
||||
pass
|
||||
|
||||
|
||||
from core.apps.vendors.models import VendorproductModel, ProductimageModel, VendorModel, CategoryModel, SectionModel
|
||||
|
||||
class CreateVendorproductSerializer(BaseVendorproductSerializer):
|
||||
uploaded_images = serializers.ListField(
|
||||
child=serializers.ImageField(max_length=1000000, allow_empty_file=False, use_url=False),
|
||||
write_only=True,
|
||||
required=False
|
||||
)
|
||||
|
||||
class Meta(BaseVendorproductSerializer.Meta):
|
||||
fields = [
|
||||
"firestore_id",
|
||||
"vendor",
|
||||
"category",
|
||||
"section",
|
||||
"name",
|
||||
"description",
|
||||
"price",
|
||||
"discount_price",
|
||||
"quantity",
|
||||
"is_publish",
|
||||
"photos_json",
|
||||
fields = BaseVendorproductSerializer.Meta.fields + [
|
||||
"uploaded_images",
|
||||
]
|
||||
|
||||
def create(self, validated_data):
|
||||
uploaded_images = validated_data.pop("uploaded_images", [])
|
||||
instance = super().create(validated_data)
|
||||
|
||||
# Save additional gallery images
|
||||
for i, img in enumerate(uploaded_images):
|
||||
ProductimageModel.objects.create(
|
||||
product=instance,
|
||||
image=img,
|
||||
order=i
|
||||
)
|
||||
return instance
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
uploaded_images = validated_data.pop("uploaded_images", [])
|
||||
instance = super().update(instance, validated_data)
|
||||
|
||||
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):
|
||||
ProductimageModel.objects.create(
|
||||
product=instance,
|
||||
image=img,
|
||||
order=instance.images.count() + i
|
||||
)
|
||||
return instance
|
||||
|
||||
2
core/apps/vendors/views/vendor_product.py
vendored
2
core/apps/vendors/views/vendor_product.py
vendored
@@ -61,7 +61,7 @@ class VendorproductView(BaseViewSetMixin, ModelViewSet):
|
||||
|
||||
|
||||
@extend_schema(tags=["ProductImage"])
|
||||
class ProductimageView(BaseViewSetMixin, ReadOnlyModelViewSet):
|
||||
class ProductimageView(BaseViewSetMixin, ModelViewSet):
|
||||
queryset = ProductimageModel.objects.all()
|
||||
serializer_class = ListProductimageSerializer
|
||||
permission_classes = [AllowAny]
|
||||
|
||||
Reference in New Issue
Block a user