Hi,
The management command product_db works with some changes made.
1. mkdir "/tmp/orig/product" where LOCAL_IMG_DIR="/tmp/orig"
2. Copy all your imagefiles to "/tmp/orig/product"
3. Make small changes as mentioned in the new product_db.py attached with 
this post.

Repeat test:

1. python manage.py product_db --export sample.csv
2. Delete the Django pony product manualy from the admin panel.
3. Import the same file
   python manage.py product_db --import sample.csv

Thanks and regards,
Sathish Anton. A

On Friday, April 29, 2016 at 11:36:33 PM UTC+5:30, Sathish Anton wrote:
>
> Hi,
> Please provide Suggestion on how to make import and export of products 
> using csv from admin panel?
>
> Thanks and Regards,
> Sathish Anton. A
>

-- 
You received this message because you are subscribed to the Google Groups 
"Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
*** product_db.py.orig	2016-05-01 18:17:25.544208670 +0530
--- product_db.py	2016-05-01 18:19:54.399766579 +0530
***************
*** 24,30 ****
  # images get copied from thie directory
  LOCAL_IMAGE_DIR = "/tmp/orig"
  # images get copied to this directory under STATIC_ROOT
! IMAGE_SUFFIXES = [".jpg", ".JPG", ".jpeg", ".JPEG", ".tif", ".gif", ".GIF"]
  EMPTY_IMAGE_ENTRIES = ["Please add", "N/A", ""]
  DATE_FORMAT = "%Y-%m-%d"
  TIME_FORMAT = "%H:%M"
--- 24,30 ----
  # images get copied from thie directory
  LOCAL_IMAGE_DIR = "/tmp/orig"
  # images get copied to this directory under STATIC_ROOT
! IMAGE_SUFFIXES = [".jpg", ".png", ".JPG", ".jpeg", ".JPEG", ".tif", ".gif", ".GIF"]
  EMPTY_IMAGE_ENTRIES = ["Please add", "N/A", ""]
  DATE_FORMAT = "%Y-%m-%d"
  TIME_FORMAT = "%H:%M"
***************
*** 48,54 ****
  
  DATETIME_FORMAT = "%s %s" % (DATE_FORMAT, TIME_FORMAT)
  SITE_MEDIA_IMAGE_DIR = _("product")
! PRODUCT_IMAGE_DIR = os.path.join(settings.STATIC_ROOT, SITE_MEDIA_IMAGE_DIR)
  TYPE_CHOICES = dict()
  for id, choice in settings.SHOP_OPTION_TYPE_CHOICES:
      TYPE_CHOICES[choice] = id
--- 48,55 ----
  
  DATETIME_FORMAT = "%s %s" % (DATE_FORMAT, TIME_FORMAT)
  SITE_MEDIA_IMAGE_DIR = _("product")
! SITE_MEDIA_IMAGE_NDIR = _("media/product")
! PRODUCT_IMAGE_DIR = os.path.join(settings.STATIC_ROOT, SITE_MEDIA_IMAGE_NDIR)
  TYPE_CHOICES = dict()
  for id, choice in settings.SHOP_OPTION_TYPE_CHOICES:
      TYPE_CHOICES[choice] = id
***************
*** 103,112 ****
      product.available = True
      # TODO: allow arbitrary level/number of categories.
      base_cat, created = Category.objects.get_or_create(title=row[CATEGORY])
!     sub_cat, created = Category.objects.get_or_create(
!         title=row[SUB_CATEGORY],
!         parent=base_cat)
!     product.categories.add(sub_cat)
      shop_cat, created = Category.objects.get_or_create(title="Shop")
      product.categories.add(shop_cat)
      return product
--- 104,114 ----
      product.available = True
      # TODO: allow arbitrary level/number of categories.
      base_cat, created = Category.objects.get_or_create(title=row[CATEGORY])
!     if row[SUB_CATEGORY]:
!         sub_cat, created = Category.objects.get_or_create(
!             title=row[SUB_CATEGORY],
!             parent=base_cat)
!         product.categories.add(sub_cat)
      shop_cat, created = Category.objects.get_or_create(title="Shop")
      product.categories.add(shop_cat)
      return product
***************
*** 125,131 ****
      shutil.copy(image_path, PRODUCT_IMAGE_DIR)
      # shutil.copy(image_path, os.path.join(PRODUCT_IMAGE_DIR, "orig"))
      image, created = ProductImage.objects.get_or_create(
!         file="%s" % (os.path.join(SITE_MEDIA_IMAGE_DIR, image_str)),
          description=image_str,  # TODO: handle column for this.
          product=product)
      return image
--- 127,133 ----
      shutil.copy(image_path, PRODUCT_IMAGE_DIR)
      # shutil.copy(image_path, os.path.join(PRODUCT_IMAGE_DIR, "orig"))
      image, created = ProductImage.objects.get_or_create(
!         file="%s" % (image_str),
          description=image_str,  # TODO: handle column for this.
          product=product)
      return image

Attachment: product_db.py.orig
Description: Binary data

from __future__ import print_function

import csv
import os
import shutil
import sys
import datetime
from optparse import make_option

from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.utils.translation import ugettext as _
from django.db.utils import IntegrityError
from mezzanine.conf import settings

from cartridge.shop.models import Product
from cartridge.shop.models import ProductOption
from cartridge.shop.models import ProductImage
from cartridge.shop.models import ProductVariation
from cartridge.shop.models import Category
from mezzanine.core.models import CONTENT_STATUS_PUBLISHED


# images get copied from thie directory
LOCAL_IMAGE_DIR = "/tmp/orig"
# images get copied to this directory under STATIC_ROOT
IMAGE_SUFFIXES = [".jpg", ".png", ".JPG", ".jpeg", ".JPEG", ".tif", ".gif", ".GIF"]
EMPTY_IMAGE_ENTRIES = ["Please add", "N/A", ""]
DATE_FORMAT = "%Y-%m-%d"
TIME_FORMAT = "%H:%M"

# Here we define what column headings are used in the csv.
TITLE = _("Title")
CONTENT = _("Content")
DESCRIPTION = _("Description")
SKU = _("SKU")
IMAGE = _("Image")
CATEGORY = _("Category")
SUB_CATEGORY = _("Sub-Category")
# SIZE = _("Size")
NUM_IN_STOCK = _("Number in Stock")
UNIT_PRICE = _("Unit Price")
SALE_PRICE = _("Sale Price")
SALE_START_DATE = _("Sale Start Date")
SALE_START_TIME = _("Sale Start Time")
SALE_END_DATE = _("Sale End Date")
SALE_END_TIME = _("Sale End Time")

DATETIME_FORMAT = "%s %s" % (DATE_FORMAT, TIME_FORMAT)
SITE_MEDIA_IMAGE_DIR = _("product")
SITE_MEDIA_IMAGE_NDIR = _("media/product")
PRODUCT_IMAGE_DIR = os.path.join(settings.STATIC_ROOT, SITE_MEDIA_IMAGE_NDIR)
TYPE_CHOICES = dict()
for id, choice in settings.SHOP_OPTION_TYPE_CHOICES:
    TYPE_CHOICES[choice] = id

fieldnames = [TITLE, CONTENT, DESCRIPTION, CATEGORY, SUB_CATEGORY,
    SKU, IMAGE, NUM_IN_STOCK, UNIT_PRICE,
    SALE_PRICE, SALE_START_DATE, SALE_START_TIME, SALE_END_DATE, SALE_END_TIME]
# TODO: Make sure no options conflict with other fieldnames.
fieldnames += TYPE_CHOICES.keys()


class Command(BaseCommand):
    args = '--import/--export <csv_file>'
    help = _('Import/Export products from a csv file.')

    option_list = BaseCommand.option_list + (
        make_option('--import',
            action='store_true',
            dest='import',
            default=False,
            help=_('Import products from csv file.')),
        make_option('--export',
            action='store_true',
            dest='export',
            default=False,
            help=_('Export products from csv file.')),
    )

    def handle(self, *args, **options):
        if sys.version_info[0] == 3:
            raise CommandError("Python 3 not supported")
        try:
            csv_file = args[0]
        except IndexError:
            raise CommandError(_("Please provide csv file to import"))
        if options["import"] and options["export"]:
            raise CommandError("can't both import and export")
        if not options["import"] and not options["export"]:
            raise CommandError(_("need to import or export"))
        if options['import']:
            import_products(csv_file)
        elif options['export']:
            export_products(csv_file)


def _product_from_row(row):
    product, created = Product.objects.get_or_create(title=row[TITLE])
    product.content = row[CONTENT]
    product.description = row[DESCRIPTION]
    # TODO: set the 2 below from spreadsheet.
    product.status = CONTENT_STATUS_PUBLISHED
    product.available = True
    # TODO: allow arbitrary level/number of categories.
    base_cat, created = Category.objects.get_or_create(title=row[CATEGORY])
    if row[SUB_CATEGORY]:
        sub_cat, created = Category.objects.get_or_create(
            title=row[SUB_CATEGORY],
            parent=base_cat)
        product.categories.add(sub_cat)
    shop_cat, created = Category.objects.get_or_create(title="Shop")
    product.categories.add(shop_cat)
    return product


def _make_image(image_str, product):
    if image_str in EMPTY_IMAGE_ENTRIES:
        return None
    # try adding various image suffixes, if none given in original filename.
    root, suffix = os.path.splitext(image_str)
    if suffix not in IMAGE_SUFFIXES:
        raise CommandError("INCORRECT SUFFIX: %s" % image_str)
    image_path = os.path.join(LOCAL_IMAGE_DIR, image_str)
    if not os.path.exists(image_path):
        raise CommandError("NO FILE %s" % image_path)
    shutil.copy(image_path, PRODUCT_IMAGE_DIR)
    # shutil.copy(image_path, os.path.join(PRODUCT_IMAGE_DIR, "orig"))
    image, created = ProductImage.objects.get_or_create(
        file="%s" % (image_str),
        description=image_str,  # TODO: handle column for this.
        product=product)
    return image


def _make_date(date_str, time_str):
    date_string = '%s %s' % (date_str, time_str)
    date = datetime.datetime.strptime(date_string, DATETIME_FORMAT)
    return date


def import_products(csv_file):
    print(_("Importing .."))
    # More appropriate for testing.
    # Product.objects.all().delete()
    reader = csv.DictReader(open(csv_file), delimiter=',')
    for row in reader:
        print(row)
        product = _product_from_row(row)
        try:
            variation = ProductVariation.objects.create(
                # strip whitespace
                sku=row[SKU].replace(" ", ""),
                product=product,
            )
        except IntegrityError:
            raise CommandError("Product with SKU exists! sku: %s" % row[SKU])
        if row[NUM_IN_STOCK]:
            variation.num_in_stock = row[NUM_IN_STOCK]
        if row[UNIT_PRICE]:
            variation.unit_price = row[UNIT_PRICE]
        if row[SALE_PRICE]:
            variation.sale_price = row[SALE_PRICE]
        if row[SALE_START_DATE] and row[SALE_START_TIME]:
            variation.sale_from = _make_date(row[SALE_START_DATE],
                                                row[SALE_START_TIME])
        if row[SALE_END_DATE] and row[SALE_END_TIME]:
            variation.sale_to = _make_date(row[SALE_END_DATE],
                                                row[SALE_END_TIME])
        for option in TYPE_CHOICES:
            if row[option]:
                name = "option%s" % TYPE_CHOICES[option]
                setattr(variation, name, row[option])
                new_option, created = ProductOption.objects.get_or_create(
                    type=TYPE_CHOICES[option],  # TODO: set dynamically
                    name=row[option])
        variation.save()
        image = _make_image(row[IMAGE], product)
        if image:
            variation.image = image
        product.variations.manage_empty()
        product.variations.set_default_images([])
        product.copy_default_variation()
        product.save()

    print("Variations: %s" % ProductVariation.objects.all().count())
    print("Products: %s" % Product.objects.all().count())


def export_products(csv_file):
    print(_("Exporting .."))
    filehandle = open(csv_file, 'w')
    writer = csv.DictWriter(filehandle, delimiter=',', fieldnames=fieldnames)
    headers = dict()
    for field in fieldnames:
        headers[field] = field
    writer.writerow(headers)
    for pv in ProductVariation.objects.all():
        row = dict()
        row[TITLE] = pv.product.title
        row[CONTENT] = pv.product.content
        row[DESCRIPTION] = pv.product.description
        row[SKU] = pv.sku
        row[IMAGE] = pv.image
        # TODO: handle multiple categories, and multiple levels of categories
        cat = pv.product.categories.all()[0]
        if cat.parent:
            row[SUB_CATEGORY] = cat.title
            row[CATEGORY] = cat.parent.title
        else:
            row[CATEGORY] = cat.title
            row[SUB_CATEGORY] = ""

        for option in TYPE_CHOICES:
            row[option] = getattr(pv, "option%s" % TYPE_CHOICES[option])

        row[NUM_IN_STOCK] = pv.num_in_stock
        row[UNIT_PRICE] = pv.unit_price
        row[SALE_PRICE] = pv.sale_price
        try:
            row[SALE_START_DATE] = pv.sale_from.strftime(DATE_FORMAT)
            row[SALE_START_TIME] = pv.sale_from.strftime(TIME_FORMAT)
        except AttributeError:
            pass
        try:
            row[SALE_END_DATE] = pv.sale_to.strftime(DATE_FORMAT)
            row[SALE_END_TIME] = pv.sale_to.strftime(TIME_FORMAT)
        except AttributeError:
            pass
        writer.writerow(row)
    filehandle.close()

Reply via email to