0

tl;dr 如何更改add-product-to-cart-footer添加一个不同模型的实例,该模型是该产品和其他信息的组合?

我是卖眼镜的,所以虽然我们的产品详细信息页面显示了镜架和镜架变体(因颜色和尺寸而异)信息,但客户还需要填写一份表格,说明他们希望使用该镜架获得哪种类型的镜片.

一种选择可能是将框架变体和镜片组合的每个排列存储为数据库中的框架变体,例如智能手机的不同存储选项,但我认为这不是一个好主意,因为:

  • 有几十种可能的镜头选择
  • 可用的镜片基本上独立于所选的镜架
  • 如果我们只有框架变体 + 镜片对象,则很难存储框架变体库存的信息。(我使用的是 Django Shop 1.1,它增加了管理库存。)

相反,我正在考虑使用带有外键的眼镜模型,用于框架变体和镜片,这就是将添加到购物车中的内容。

class Lenses(models.Model):
    material = models.CharField(choices=...)
    anti_reflective = models.CharField(choices=...)
    # ...

class Glasses(models.Model):
    frame = models.ForeignKey(FrameVariant)
    lenses = models.ForeignKey(Lenses)

我想修改“添加到购物车”按钮,而不是将框架变体添加到购物车,而是转到一个表格(可能覆盖在同一页面上)来选择镜片。要覆盖的相关块add-product-to-cart-footer来自shop/catalog/product-add2cart

{% block add-product-to-cart-footer %}
  <div class="card-footer bg-white">
    <div class="d-flex flex-column flex-lg-row justify-content-between">
      <button class="btn btn-secondary m-1" ng-disabled="context.is_in_cart" ng-click="do(addToCart('{% url "shop:watch-list" %}'))">
        {% trans "Watch product" %}
        <i class="fa" ng-class="context.is_in_cart ? 'fa-heart' : 'fa-heart-o'"></i>
      </button>
      {% url "shop:cart-list" as cart_endpoint %}{% trans "The product has been successfully placed in the shopping cart:" as modal_title %}
      <button
        class="btn btn-primary m-1"
        ng-disabled="!context.availability.quantity"
        ng-click="
          {% if use_modal_dialog %}
            do(openModal('{{ modal_title }}'))
              .then(addToCart('{{ cart_endpoint }}'))
              .then(redirectTo())
          {% else %}
            do(addToCart('{{ cart_endpoint }}'))
              .then(emit('shop.cart.change'))
          {% endif %}
        "
      >
        {% trans "Add to cart" %}
        <i class="fa fa-cart-arrow-down"></i>
      </button>
    </div>
    {% if request.session.is_empty %}
      <small class="text-muted m-1">{% block cookie-disclaimer %}
        {% blocktrans %}By adding a product to the cart you are giving consent to cookies being used.{% endblocktrans %}
      {% endblock %}</small>
    {% endif %}
  </div>
{% endblock add-product-to-cart-footer %}

addToCart(endpoint)来自商店/静态/商店/js/catalog.js:

scope.addToCart = function(endpoint) {
	return function(context) {
		var deferred = $q.defer();
		$http.post(endpoint, scope.context).then(function(response) {
			scope.context.is_in_cart = true;
			deferred.resolve(context);
		}).catch(function(response) {
			$log.error('Unable to update context: ' + response.statusText);
			deferred.reject();
		});
		return deferred.promise;
	};
};

看起来context是什么决定了添加到购物车中的内容,所以这就是我必须更改的内容。似乎context可能正在经过shop/cascade/catalog.py

class ShopAddToCartPlugin(ShopPluginBase):
    name = _("Add Product to Cart")
    require_parent = True
    parent_classes = ('BootstrapColumnPlugin',)
    cache = False

    use_modal_dialog = GlossaryField(
        widgets.CheckboxInput(),
        label=_("Use Modal Dialog"),
        initial='on',
        help_text=_("After adding product to cart, render a modal dialog"),
    )

    def get_render_template(self, context, instance, placeholder):
        templates = []
        if instance.glossary.get('render_template'):
            templates.append(instance.glossary['render_template'])
        if context['product'].managed_availability():
            template_prefix = 'available-'
        else:
            template_prefix = ''
        templates.extend([
            '{}/catalog/{}product-add2cart.html'.format(app_settings.APP_LABEL, template_prefix),
            'shop/catalog/{}product-add2cart.html'.format(template_prefix),
        ])
        return select_template(templates)

    def render(self, context, instance, placeholder):
        context = super(ShopAddToCartPlugin, self).render(context, instance, placeholder)
        context['use_modal_dialog'] = bool(instance.glossary.get('use_modal_dialog', True))
        return context

查找 ShopAddToCartPlugin 在 Django Shop 代码或 Cookiecutter 生成的内容中都没有发现任何值得注意的用法,所以我不确定context将传递给render.

编辑:另一个选项是像往常一样将框架变体添加到购物车,但重定向到创建与该框架变体相关联的 Lenses 对象的镜头形式。这似乎可以更简单。

为了帮助可视化模板,Django Shop 如下所示: Django Shop 产品详情截图

4

1 回答 1

1

在类似的用例中,我将产品作为单独的物品保存在购物车中。这意味着,我不会使用 to 的外GlassesLenses

相反,我会创建一个特殊的AddGlassCartSerializer(...),它检查提供的(发布的)数据。在那里我会区分框架,左右镜头。如果您提供各向异性变体,您甚至可能必须跟踪镜头方向。

然后,将玻璃杯添加到购物车后,您总是会得到 3 件物品:镜框、左镜片和右镜片。

于 2019-08-07T20:51:38.060 回答