Vendor Product Management API Documentation
Overview
The VendorProductViewSet API handles the listing, creation, retrieval, updating and deleteing of products for vendors. Only users with the vendor or vendor_role roles can create products. The API also includes pagination, filtering, and ordering features.
Class: VendorProductViewSet
Permissions
- HasVendorRolePermission: Custom permission class ensuring that only users with the
vendororvendor_rolerole can create products. The permission is checked before allowing access to thecreatemethod.
Required Role
- Product Management: Only users with the appropriate role (e.g.,
vendororvendor_role) can access this API endpoint for creating a product.
Serializer Class
-
ProductSerializer: Used to serialize the product data for creating a new product. The ProductSerializer handles the serialization of the Product model and its associated fields, including product variants, shop details, and ratings. Below are key methods and fields of the
ProductSerializer: -
Fields: id, name, slug, status, vendor, shop, discount_percent, description, is_featured, is_active, images, video, color_variants, parent_category, average_rating, total_reviews, recommended_percentage, rating_summary, brand, fabric, popularity, wishlist_count, cart_item_count, total_sold_count, product_stock, category, subcategory, collection, collection_id, created_at, updated_at, discounted_price, is_product_wishlisted, shop_details, comment, product_variant, product_specification, additional_information, detailed_product_description, is_customizable, customized_price, measurement_fields
- images: A list of
ProductImageSerializerobjects representing the images associated with the product. - color_variants: A method field that retrieves color variants for the product.
- parent_category: A method field that retrieves the parent category of the product.
- average_rating: The average rating of the product.
- total_reviews: The total number of reviews for the product.
- recommended_percentage: The percentage of recommended products.
- rating_summary: A summary of the product's ratings.
- brand: The brand associated with the product.
- fabric: The fabric type of the product.
- popularity: The popularity of the product.
- wishlist_count: The number of times the product has been added to a wishlist.
- images: A list of
-
Method Fields:
- get_color_variants: Retrieves all the available color variants for the product, including size, stock, price, and availability.
- get_parent_category: Returns the parent category of the product.
- get_shop_details: Retrieves the shop details, including the vendor, location, and ratings.
- calculate_average_ratings: Calculates the average ratings for the shop based on user reviews.
-
Validation Methods:
- validate_category: Ensures that the category provided is valid.
- validate_subcategory: Ensures that the subcategory is a child of the selected category.
Pagination
- CustomPagination: Custom pagination class is used to paginate the product listing when retrieved via the
GETmethod.
Filter Backends
- OrderingFilter: Allows filtering and ordering of product listings based on several fields such as
discounted_price,avg_rating,created_at, etc.
Ordering Fields
- Products can be ordered by the following fields:
discounted_priceavg_ratingcreated_atdiscount_percenttotal_reviewsupdated_at-
recommended_percentage -
The default ordering is by
updated_atin descending order (-updated_at).
Methods
GET /api/v1/catalog/vendor/product/: Lists products with pagination, filtering, and ordering.POST /api/v1/catalog/vendor/product/: Creates a new product for the vendor.PATCH /api/v1/catalog/vendor/product/<int:pk>/: Update a new product for the vendor.DELETE /api/v1/catalog/vendor/product/<int:pk>/: Delete a new product for the vendor.
Get Product Method: get
Response
{
"pageSize": 20,
"count": 1,
"page_count": 1,
"active_page": 1,
"next": null,
"previous": null,
"results": [
{
"id": 8,
"name": "Banarasi Saari",
"slug": "banarasi-saari",
"status": "Approved",
"vendor": 10,
"shop": 2,
"discount_percent": "11.00",
"description": "Banarasi Saari",
"is_featured": false,
"is_active": true,
"images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"variant": 49,
"is_primary": true,
"created_at": "03-07-2025 11:15:20"
},
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"variant": 50,
"is_primary": false,
"created_at": "03-07-2025 11:15:31"
}
],
"video": null,
"color_variants": [
{
"color": "Navy",
"value": "NV-LG",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 50,
"size": {
"id": 2,
"size": "Large",
"value": "L"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 10,
"is_available": true,
"is_active": true
}
],
"total_stock": 10,
"is_available": true,
"variant_images": [
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"is_primary": false
}
]
},
{
"color": "Rosy Brown",
"value": "RB - FE",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 49,
"size": {
"id": 4,
"size": "Free",
"value": "FE"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 9,
"is_available": true,
"is_active": true
}
],
"total_stock": 9,
"is_available": true,
"variant_images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"is_primary": true
}
]
}
],
"parent_category": {
"id": 1,
"name": "Saree",
"slug": "saree",
"description": "Saree as Main category",
"banner_image": null,
"thumbnail_image": null,
"specific_child": {
"id": 4,
"name": "Amazing Sarees",
"slug": "amazing-sarees",
"description": "",
"banner_image": null,
"thumbnail_image": null,
"created_at": "02-03-2025 07:19:26",
"updated_at": "02-03-2025 07:19:26"
},
"created_at": "02-03-2025 07:18:25",
"updated_at": "02-03-2025 07:18:25"
},
"average_rating": 0.0,
"total_reviews": 0,
"recommended_percentage": 0,
"rating_summary": {
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0
},
"brand": 2,
"fabric": 4,
"popularity": 0,
"wishlist_count": 0,
"cart_item_count": 0,
"total_sold_count": 1,
"product_stock": 19,
"category": 4,
"collection": null,
"created_at": "03-07-2025 11:13:32",
"updated_at": "03-07-2025 11:13:32",
"discounted_price": 16.02,
"shop_details": {
"id": 2,
"name": "Hannah Jackson Vendor",
"description": "",
"location": "Dallas",
"image": "http://127.0.0.1:8000/media/shop/images/452635983_779685020743037_6966772496551245287_n.jpg",
"cover_image": null,
"follower_count": 0,
"average_rating": 0
},
"comment": "",
"product_specification": "nth",
"additional_information": "cjsnd",
"detailed_product_description": "sdvfs",
"is_customizable": false,
"customized_price": null,
"measurement_fields": [],
"available_subcategories": [],
"is_product_wishlisted": false
}
]
}
Create Product Method: create
The create method is responsible for handling the creation of a product. It involves validating the user's role, extracting product data from the request, and creating product variants.
Request Data Validation
-
Role Verification:
- If the user’s role is
user, a validation error is raised because only vendors or vendor roles are allowed to create products. - If the user’s role is
vendor, the corresponding vendor instance and shop are retrieved. - If the user’s role is
vendor_role, the associated vendor is retrieved throughVendorRolePermissions. If no vendor is found, a validation error is raised.
- If the user’s role is
-
Shop Association:
- The shop associated with the vendor is retrieved. If no shop is associated, a validation error is raised.
-
Product Variants:
- At least one product variant is required. The variants' data must include color, size, stock quantity, and price.
-
Variant Processing:
- For each variant:
- Validates if the size exists in the database.
- Checks for duplicates in the color, value, and size combination to ensure no variant duplication.
- Validates whether the size is available and whether the variant is active.
- For each variant:
-
Slug Generation:
- A slug for the product is generated from the name. If the slug already exists in the database, a counter is appended to the slug to ensure uniqueness.
-
Subcategory Handling:
- If a subcategory is provided, it is retrieved from the database.
-
Product Status:
- The product is set to a status of "Pending". If no "Pending" status exists, a validation error is raised.
-
Brand, Collection, and Fabric:
- If provided, the brand, collection, and fabric are retrieved. If any of them do not exist, they are set to
None.
- If provided, the brand, collection, and fabric are retrieved. If any of them do not exist, they are set to
-
Measurement Fields:
- If the product is customizable, measurement fields are validated and associated with the product.
Transaction Handling
The creation of the product and its associated variants is wrapped in a database transaction using transaction.atomic(). This ensures that if any error occurs, all database changes are rolled back to maintain consistency. This guarantees that either the product and all variants are created successfully, or none of them are created.
Variant Creation
For each variant: 1. The size is validated to ensure it exists in the database. 2. Duplicates are checked by tracking the color, value, and size combination. 3. Images are processed and associated with the respective variant.
Variants are created in the ProductVariant model with the following fields:
- color
- value
- size
- variant_price
- stock_quantity
Additionally, images for the variant are handled and stored in the ProductImage model.
Response
Success Response:
On successful product creation, the API returns a 201 Created status with a message and the serialized product data.
Example:
{
"message": "Product created successfully!",
"data": {
"id": 8,
"name": "Banarasi Saari",
"slug": "banarasi-saari",
"status": "Approved",
"vendor": 10,
"shop": 2,
"discount_percent": "11.00",
"description": "Banarasi Saari",
"is_featured": false,
"is_active": true,
"images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"variant": 49,
"is_primary": true,
"created_at": "03-07-2025 11:15:20"
},
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"variant": 50,
"is_primary": false,
"created_at": "03-07-2025 11:15:31"
}
],
"video": null,
"color_variants": [
{
"color": "Navy",
"value": "NV-LG",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 50,
"size": {
"id": 2,
"size": "Large",
"value": "L"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 10,
"is_available": true,
"is_active": true
}
],
"total_stock": 10,
"is_available": true,
"variant_images": [
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"is_primary": false
}
]
},
{
"color": "Rosy Brown",
"value": "RB - FE",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 49,
"size": {
"id": 4,
"size": "Free",
"value": "FE"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 9,
"is_available": true,
"is_active": true
}
],
"total_stock": 9,
"is_available": true,
"variant_images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"is_primary": true
}
]
}
],
"parent_category": {
"id": 1,
"name": "Saree",
"slug": "saree",
"description": "Saree as Main category",
"banner_image": null,
"thumbnail_image": null,
"specific_child": {
"id": 4,
"name": "Amazing Sarees",
"slug": "amazing-sarees",
"description": "",
"banner_image": null,
"thumbnail_image": null,
"created_at": "02-03-2025 07:19:26",
"updated_at": "02-03-2025 07:19:26"
},
"created_at": "02-03-2025 07:18:25",
"updated_at": "02-03-2025 07:18:25"
},
"average_rating": 0.0,
"total_reviews": 0,
"recommended_percentage": 0,
"rating_summary": {
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0
},
"brand": 2,
"fabric": 4,
"popularity": 0,
"wishlist_count": 0,
"cart_item_count": 0,
"total_sold_count": 1,
"product_stock": 19,
"category": 4,
"collection": null,
"created_at": "03-07-2025 11:13:32",
"updated_at": "03-07-2025 11:13:32",
"discounted_price": 16.02,
"shop_details": {
"id": 2,
"name": "Hannah Jackson Vendor",
"description": "",
"location": "Dallas",
"image": "http://127.0.0.1:8000/media/shop/images/452635983_779685020743037_6966772496551245287_n.jpg",
"cover_image": null,
"follower_count": 0,
"average_rating": 0
},
"comment": "",
"product_specification": "nth",
"additional_information": "cjsnd",
"detailed_product_description": "sdvfs",
"is_customizable": false,
"customized_price": null,
"measurement_fields": [],
"available_subcategories": [],
"is_product_wishlisted": false
}
}
Update Product Method: update
The update method is responsible for handling the update of an existing product. It involves validating the user's role and permissions, ensuring the requested data is valid, and updating the product details along with its variants and images.
Request Data Validation
Role Verification:
- User Role:
-
If the user’s role is user, a validation error is raised because only vendors or vendor roles are allowed to update products.
-
Vendor Role:
-
If the user’s role is vendor, the corresponding vendor instance and shop are retrieved to ensure that the product being updated belongs to this vendor.
-
VendorRole Permissions:
- If the user’s role is vendor_role, the associated vendor is retrieved via
VendorRolePermissions. If no vendor is found, a validation error is raised. The vendor must have permissions to update the product.
Product Ownership:
- The product to be updated is retrieved using its id (primary key).
- If the product does not belong to the vendor making the request (i.e., the vendor is not the owner of the product), a 403 Forbidden error is raised.
Product Variants:
- If variants are provided for the update:
- The variant data must include the following fields: color, size, stock quantity, and price.
Variant Processing:
- The size must exist in the database.
- Ensure that there are no duplicate variants (duplicate combinations of color, size, and value).
- Validate that the size is available and active.
- Ensure that no variant with the same combination of color, size, and value already exists for the same product.
Slug Uniqueness:
- If the product name has changed, a slug is generated, ensuring its uniqueness by checking the database and appending a counter if needed.
Status Update:
- The status of the product can be updated. If a status like "Pending" is set, a check is made to ensure that the status exists.
- If no valid status is found, a validation error is raised.
Brand, Collection, and Fabric:
- The brand, collection, and fabric fields are updated. If they are provided, the respective objects are retrieved from the database. If any of them do not exist, they are set to None.
Measurement Fields:
- If the product is customizable, the measurement fields are validated, ensuring that they exist in the database. These fields are then associated with the product as required.
Transaction Handling
The update process for the product, its variants, and images is wrapped inside a database transaction using transaction.atomic(). This ensures that if any error occurs during the update process, the entire operation is rolled back, maintaining database consistency. This guarantees that either the product and all its variants are updated successfully or none of the changes are committed.
Variant Updates
For each updated variant:
- The size is validated to ensure it exists in the database.
- Duplicates are checked by tracking the color, value, and size combination.
- Images are processed and associated with the updated variant.
- If an image is removed, it is deleted from the database.
The variants are updated in the ProductVariant model, ensuring the following fields are accurately updated: - color - value - size - variant_price - stock_quantity
Additionally, the variant images are updated or added to the ProductImage model, ensuring the correct images are associated with the updated variant.
Handling Product Images
If any product images are provided in the request, they are:
- Checked for validity.
- Associated with the product in the ProductImage model.
- Existing product images are updated or removed as necessary based on the provided data.
Request Body:
{
"name": "Banarasi Saari",
"vendor": 1,
"shop": 1,
"description": "Updated description",
"discount_percent": 15,
"video": "https://updated_video_link",
"is_featured": true,
"product_specification": "Updated spec",
"additional_information": "Updated additional info",
"detailed_product_description": "Updated detailed description",
"comment": "Updated comment",
"popularity": 10,
"status": "Approved",
"category": 2,
"brand": 3,
"fabric": 4,
"collection": 5,
"is_customizable": true,
"customized_price": 100.00,
"product_variant": {
"color_variant1": {
"variant_id": 1,
"color": "Red",
"value": "M",
"sizes": {
"size1": {
"id": 1,
"stock_quantity": 50,
"variant_price": 120.00,
"is_available": true,
"is_active": true
}
},
"variant_images": {
"image1": {
"id": 1,
"is_primary": true,
"image": "image_link.jpg"
}
}
}
}
}
Response
Success Response:
On successful product update, the API returns a 200 OK status with a message and the serialized product data.
Example:
{
"message": "Product updated successfully!",
"data": {
"id": 8,
"name": "Banarasi Saari",
"slug": "banarasi-saari",
"status": "Approved",
"vendor": 10,
"shop": 2,
"discount_percent": "11.00",
"description": "Banarasi Saari",
"is_featured": false,
"is_active": true,
"images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"variant": 49,
"is_primary": true,
"created_at": "03-07-2025 11:15:20"
},
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"variant": 50,
"is_primary": false,
"created_at": "03-07-2025 11:15:31"
}
],
"video": null,
"color_variants": [
{
"color": "Navy",
"value": "NV-LG",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 50,
"size": {
"id": 2,
"size": "Large",
"value": "L"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 10,
"is_available": true,
"is_active": true
}
],
"total_stock": 10,
"is_available": true,
"variant_images": [
{
"id": 51,
"image": "http://127.0.0.1:8000/media/product/image/blog6_TPFXquX.jpeg",
"is_primary": false
}
]
},
{
"color": "Rosy Brown",
"value": "RB - FE",
"min_price": 18.0,
"max_price": 18.0,
"sizes": [
{
"id": 49,
"size": {
"id": 4,
"size": "Free",
"value": "FE"
},
"variant_price": 18.0,
"discounted_price": 16.02,
"stock_quantity": 9,
"is_available": true,
"is_active": true
}
],
"total_stock": 9,
"is_available": true,
"variant_images": [
{
"id": 50,
"image": "http://127.0.0.1:8000/media/product/image/blog5_jmsACHV.jpeg",
"is_primary": true
}
]
}
],
"parent_category": {
"id": 1,
"name": "Saree",
"slug": "saree",
"description": "Saree as Main category",
"banner_image": null,
"thumbnail_image": null,
"specific_child": {
"id": 4,
"name": "Amazing Sarees",
"slug": "amazing-sarees",
"description": "",
"banner_image": null,
"thumbnail_image": null,
"created_at": "02-03-2025 07:19:26",
"updated_at": "02-03-2025 07:19:26"
},
"created_at": "02-03-2025 07:18:25",
"updated_at": "02-03-2025 07:18:25"
},
"average_rating": 0.0,
"total_reviews": 0,
"recommended_percentage": 0,
"rating_summary": {
"1": 0,
"2": 0,
"3": 0,
"4": 0,
"5": 0
},
"brand": 2,
"fabric": 4,
"popularity": 0,
"wishlist_count": 0,
"cart_item_count": 0,
"total_sold_count": 1,
"product_stock": 19,
"category": 4,
"collection": null,
"created_at": "03-07-2025 11:13:32",
"updated_at": "03-07-2025 11:13:32",
"discounted_price": 16.02,
"shop_details": {
"id": 2,
"name": "Hannah Jackson Vendor",
"description": "",
"location": "Dallas",
"image": "http://127.0.0.1:8000/media/shop/images/452635983_779685020743037_6966772496551245287_n.jpg",
"cover_image": null,
"follower_count": 0,
"average_rating": 0
},
"comment": "",
"product_specification": "nth",
"additional_information": "cjsnd",
"detailed_product_description": "sdvfs",
"is_customizable": false,
"customized_price": null,
"measurement_fields": [],
"available_subcategories": [],
"is_product_wishlisted": false
}
}
Delete Product Method: delete
The delete method is responsible for handling the deletion of an existing product. It involves validating the user's role and permissions, ensuring that the product exists, and then deleting the product along with its variants and images.
Request Data Validation
Role Verification:
- User Role:
-
If the user’s role is user, a validation error is raised because only vendors or vendor roles are allowed to delete products.
-
Vendor Role:
-
If the user’s role is vendor, the corresponding vendor instance and shop are retrieved to ensure that the product being deleted belongs to this vendor.
-
VendorRole Permissions:
- If the user’s role is vendor_role, the associated vendor is retrieved via
VendorRolePermissions. If no vendor is found, a validation error is raised. The vendor must have permissions to delete the product.
Product Ownership:
- The product to be deleted is retrieved using its id (primary key).
- If the product does not belong to the vendor making the request (i.e., the vendor is not the owner of the product), a 403 Forbidden error is raised.
Product Existence Check:
- Before proceeding with the deletion, the product is checked to ensure that it exists in the database.
- If the product does not exist, a 404 Not Found error is raised.
Variant and Image Deletion:
- All variants associated with the product are deleted from the ProductVariant model.
- All images associated with the product are deleted from the ProductImage model.
- The variants and images are deleted safely, ensuring that the operation does not affect other records in the database.
Transaction Handling
The delete process for the product, its variants, and images is wrapped inside a database transaction using transaction.atomic(). This ensures that if any error occurs during the deletion process, the entire operation is rolled back, maintaining database consistency. This guarantees that either the product and all its variants and images are deleted successfully, or none of the changes are committed.
Deletion Process
The following actions are performed during the deletion process: 1. The product is retrieved using its id (primary key). 2. The variants associated with the product are deleted from the ProductVariant model. 3. The images associated with the product are deleted from the ProductImage model. 4. The product itself is deleted from the Product model.
Soft Deletion (Optional):
If soft deletion is implemented, the product and its related data may be marked as deleted (e.g., with a deleted_at timestamp) rather than being removed from the database entirely.
Success Response
- If the deletion is successful, a 204 No Content response is returned, indicating that the product and its associated variants and images were successfully deleted.
Failure Response
- If any error occurs during the deletion process, a 500 Internal Server Error response is returned.