Создать канонический "родительский" продукт в Django Oscar программно

Я пытаюсь использовать модифицированную версию класса django-oscar import_oscar_catalogue, чтобы импортировать несколько продуктов из CSV, и при первом обращении к продукту (определяется по названию) создать канонический родительский продукт, а затем для всех будущие встречи создают дочерний продукт под этим родительским продуктом.

Кажется, это работает, но канонический продукт не отражает объединенные уровни запасов дочернего продукта и не отображает правильные атрибуты для этого продукта. Тем не менее, он правильно перечисляет их как варианты на панели инструментов django.

Как программно создать эти дочерние / родительские отношения в продуктах с правильными учетными записями?

Соответствующий код:

def _create_item(self, upc, title, product_class, other_product_attributes):
    product_class, __ \
        = ProductClass.objects.get_or_create(name=product_class)
    try:
        parent = Product.objects.get(title=title)
        item = Product()
        item.parent = parent
    except Product.DoesNotExist:
        # Here is where I think it might need to be changed
        # Maybe pitem = ParentProduct() or something?
        pitem = Product()
        pitem.upc = upc
        pitem.title = title
        pitem.other_product_attributes = other_product_attributes
        # Here parent item is saved to db
        pitem.save()
        # Create item because no parent was found
        item = Product()
        parent = Product.objects.get(title=title)
        #Set parent
        item.parent = parent
    # Customize child attributes
    item.product_class = product_class
    item.title = title
    item.other_product_attributes = other_product_attributes
    # Save the child item
    item.save()

def _create_stockrecord(self, item, partner_name, partner_sku, price_excl_tax,
    num_in_stock, stats):
    # Create partner and stock record
    partner, _ = Partner.objects.get_or_create(
        name=partner_name)
    try:
        stock = StockRecord.objects.get(partner_sku=partner_sku)
    except StockRecord.DoesNotExist:
        stock = StockRecord()
        stock.num_in_stock = 0
    # General attributes
    stock.product = item
    stock.partner = partner
    # SKU will be unique for every object
    stock.partner_sku = partner_sku
    stock.price_excl_tax = D(price_excl_tax)
    stock.num_in_stock += int(num_in_stock)
    # Save the object to database
    stock.save()

Create_stockrecord() создает запись из 1 запаса для каждого уникального варианта элемента, но записи этого варианта не переводятся в родительский элемент.

Спасибо за любые предложения.

РЕДАКТИРОВАТЬ: я обновил класс с методом, который явно вызывает ProductClass.objects.track_stock() для экземпляра ProductClass, и я вызываю его после циклического прохождения всех строк файла CSV (передавая имя одного продукта класс я использую сейчас). Однако при просмотре запаса на панели инструментов ни один из дочерних / вариационных запасов не учитывается по отношению к родительскому.

def track_stock(self, class_name):
    self.logger.info("ProductClass name: %s" % class_name)
    product_class = ProductClass.objects.get_or_create(name=class_name)
    self.logger.info("ProductClass: %s" % str(product_class))
    self.logger.info("TrackStock: %s" % str(product_class[0].track_stock))
    product_class[0].track_stock = True
    self.logger.info("TrackStock: %s" % str(product_class[0].track_stock))
    product_class[0].save()


INFO Starting catalogue import
INFO  - Importing records from 'sample_inventory.csv'
INFO  - Flushing product data before import
INFO Parent items: 6, child items: 10
INFO ProductClass name: ClassName
INFO ProductClass: (<ProductClass: ClassName>, False)
INFO TrackStock: True
INFO TrackStock: True

Я проверил страницу администратора, только 1 ProductClass создан, и у него есть то же имя, которое передается в track_stock(). Есть ли что-то еще, что нужно сделать, чтобы включить эту функцию? Документация track_stock () довольно редкая. В выводе track_stock выглядит так, как будто это правда в обоих случаях. Должен ли он быть False при создании child_objects, а затем переключаться в True?

РЕДАКТИРОВАТЬ: РЕШЕНИЕ:

После некоторых исследований на тестовом заводе я решил проблему, указав

product.stucture = 'parent' 

На родительском объекте и

product.structure = 'child'

на дочернем объекте. Мне также нужно было изменить пользовательские атрибуты моих объектов на dict product_attributes, а затем установите каждое значение на объекте:

if product_attributes:
        for code, value in product_attributes.items():
            product_class.attributes.get_or_create(name=code, code=code)
            setattr(product.attr, code, value)

Не было необходимости создавать запись запаса для каждого родительского объекта, так как они отслеживают записи запаса дочерних объектов, с которыми они связаны. Также не было необходимости устанавливать track_stock = True, как это установлено в True по умолчанию при создании Product()

2 ответа

Чтобы иметь возможность правильно отражать уровни запасов для любого Продукта, у вас должен быть Партнер, который будет поставлять Продукт, а затем вам нужно иметь StockRecord, который связывает Партнера и Продукты вместе.

Сначала убедитесь, что у вас есть вся эта информация в базе данных для каждого из ваших вариантов продукта.

Затем вам нужно обновить ваш ProductClass и установить для атрибута track_stock значение True, поскольку по умолчанию его значение None.

Вам также необходимо удалить ProductClass из ваших дочерних продуктов, поскольку они наследуют ProductClass от своего родительского продукта.

РЕДАКТИРОВАТЬ 1:

Чтобы добавить атрибуты к продукту, вы должны добавить ProductAttribute для ProductClass, а затем вы можете установить атрибуты непосредственно на Product, как в этом примере.

РЕДАКТИРОВАТЬ 2:

Вам также необходимо установить "net_stock_level" в StockRecord.

Чтобы получить более глубокое представление о том, как Оскар получает уровни запасов, посмотрите в Selector. Этот класс определяет, какие стратегии ценообразования, налогообложения и уровня запасов использовать, которые вам, возможно, потребуется настроить в будущем, если вы хотите взимать налог или предлагать различные цены в зависимости от пользователя.

После некоторых исследований на тестовой фабрике я решил проблему, указав

      product.stucture = 'parent' 

На родительском объекте и

      product.structure = 'child'

на дочернем объекте. Мне также нужно было изменить пользовательские атрибуты моих объектов на dictproduct_attributes, а затем установите каждое значение для объекта:

      if product_attributes:
        for code, value in product_attributes.items():
            product_class.attributes.get_or_create(name=code, code=code)
            setattr(product.attr, code, value)

Нет необходимости создавать учетную запись для каждого родительского объекта, поскольку они отслеживают записи о запасах дочерних объектов, с которыми они связаны. тоже не надо было ставитьtrack_stock = True, так как установленоTrueпо умолчанию при созданииProduct()


Этот ответ был опубликован как редактирование вопроса. Создайте канонический «родительский» продукт в Django Oscar программно с помощью OP user1751129 под CC BY-SA 3.0.

Другие вопросы по тегам