Создавать канонический "родительский" продукт в Django Oscar программно
Я пытаюсь использовать модифицированную версию класса django-oscar import_oscar_catalogue для импорта кучи продуктов из CSV и при первом столкновении с продуктом (определяется заголовком) создайте канонический родительский продукт, а затем для всех будущих встреч создайте дочерний продукт под этим родительским продуктом.
Это похоже на работу, но канонический продукт не отражает совокупные уровни запасов дочернего продукта и не отображает правильные атрибуты для этого продукта. Однако он правильно отображает их как изменения в панели django.
Как я могу программно создать это отношение child/parent в продуктах с правильными учетными записями?
Соответствующий код:
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 запаса для каждого уникального варианта предмета, но эти вариационные скобки не переводятся в родительский элемент.
Спасибо за любые предложения.
EDIT:
Я обновил класс с помощью метода, который явно вызывает 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, пока создаются дочерние_объекты, а затем перевернуты на True?
ИЗМЕНИТЬ: РЕШЕНИЕ:
После некоторого исследования test factory я решил проблему, указав
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()
Ответы
Ответ 1
Чтобы иметь возможность правильно отражать уровни запасов для любого Product, вам нужно Partner, который будет поставлять Продукт, а затем вам нужно StockRecord, которое связывает Партнера и Продукты вместе.
Сначала убедитесь, что у вас есть вся эта информация в базе данных для каждой из ваших Product.
Затем вам нужно обновить ProductClass и установить track_stock "как True, поскольку по умолчанию None.
Вам также необходимо удалить ProductClass из ваших дочерних продуктов, поскольку они наследуют ProductClass из их родительского продукта.
ИЗМЕНИТЬ 1:
Чтобы добавить атрибуты к продукту, вы должны добавить ProductAttribute для ProductClass, а затем вы можете установить атрибуты непосредственно на Product как этот пример.
ИЗМЕНИТЬ 2:
Вам также нужно установить "net_stock_level" в StockRecord.
Чтобы получить более глубокое представление о том, как Оскар получает уровни запасов, просмотрите Селектор. Этот класс определяет, какие стратегии ценообразования, налогов и уровня запасов использовать, которые вам могут понадобиться для настройки в будущем, если вы хотите взимать налог или предлагать разные цены на основе пользователя.