2017-03-27 07:29:35 +00:00
.. _tutorial_products:
Managing the Catalogue
======================
2017-03-30 19:24:37 +00:00
Creating the Product Index
--------------------------
Wagtails' `` Page `` models are organized in a tree structure. All our `` Product `` pages will therefore
2017-03-30 20:17:02 +00:00
need a parent. This is provided by the `` ProductIndex `` model.
2017-03-30 19:24:37 +00:00
.. note ::
Read more about Wagtail pages in the `Wagtail docs <http://docs.wagtail.io/en/v1.9/topics/pages.html> `_
2017-03-30 20:17:02 +00:00
To add a product index page:
2017-03-30 19:24:37 +00:00
2017-03-30 20:17:02 +00:00
- Navigate to the admin and log in
2017-03-30 19:24:37 +00:00
- Select the homepage from the explorer menu
- Select `` add child page ``
2017-03-30 20:17:02 +00:00
- Select `` Product index `` and enter the title (e.g. `Products` )
2017-03-30 19:24:37 +00:00
.. figure :: ../_static/images/product_index.png
2017-03-30 20:17:02 +00:00
We can now add `` Product `` models as children of `` ProductIndex `` . Only pages of type `` Product `` can be created under `` ProductIndex `` .
2017-03-30 19:24:37 +00:00
2017-03-30 20:17:02 +00:00
Adding a Product
----------------
2017-03-30 19:24:37 +00:00
2017-03-30 20:17:02 +00:00
Under the explorer homepage, we should now see our newly created `` ProductIndex `` . We can select `` Add child page `` to add our first
`` Product `` . The `` Product `` model is fairly minimal. It has:
2017-03-30 19:24:37 +00:00
2017-03-30 20:17:02 +00:00
- A title
- A description
- One or more `` ProductVariant ` ` s
- Optionally some images and tags
2017-03-30 19:24:37 +00:00
2017-03-30 20:17:02 +00:00
.. figure :: ../_static/images/product.png
2017-03-27 07:29:35 +00:00
Customising Variants
--------------------
2017-03-30 20:17:02 +00:00
The `` ProductVariant `` model is where we can customise the attributes of our model. Running `` longclaw start ``
provided a `` products `` with a minimal implementation of a custom `` ProductVariant `` model.
We can further customise this now by opening `` my_shop/products/models.py `` in a text editor.
`` ProductVariant `` inherits from `` ProductVariantBase `` which provides the `` price `` , `` ref `` and `` slug `` fields.
The `` ref `` field is intended to be used as a short description or sub-title to help distinguish a particular variant.
The `` slug `` field is autogenerated from the `` ref `` and the parent `` Product `` title.
2017-04-05 13:32:22 +00:00
As we are creating a music shop, we are going to add a `` music_format `` field to the model. We will also
2017-03-30 20:17:02 +00:00
remove the `` description `` field as we dont have any real need for it at the moment:
.. code :: python
class ProductVariant(ProductVariantBase):
2017-04-05 13:32:22 +00:00
_MUSIC_FORMAT_CHOICES = (
(1, 'CD'),
(2, 'Vinyl'),
2017-03-30 20:17:02 +00:00
)
2017-04-05 13:32:22 +00:00
music_format = models.IntegerField(max_length=3, choices=_MUSIC_FORMAT_CHOICES)
2017-03-30 20:17:02 +00:00
2017-04-05 13:32:22 +00:00
After making and running migrations, we can now select the format for each variant:
2017-03-30 20:17:02 +00:00
.. figure :: ../_static/images/product_variant.png
2017-03-27 07:29:35 +00:00
2017-03-30 20:17:02 +00:00
The actual model used for the product variant can be changed by changing the `` PRODUCT_VARIANT_MODEL `` setting in your `` settings.py ``
2017-03-30 20:39:50 +00:00
Creating the Front End
=======================
Since `` ProductIndex `` and `` Product `` are Wagtail pages, we write templates for them just like any other page.
The Wagtail documentation already comprehensively covers `writing templates <http://docs.wagtail.io/en/v1.9/topics/writing_templates.html> `_ .
Our template project already has some basic templates for `` ProductIndex `` and `` Product `` :
- `` my_shop/my_shop/templates/longclawproducts/product_index.html ``
- `` my_shop/my_shop/templates/longclawproducts/product.html ``
They contain just enough information to demonstrate how to traverse the products and their fields.
For a more complete template, take a look at the `demo project <https://github.com/JamesRamm/longclaw_demo> `_ .
2017-03-30 20:52:59 +00:00
Adding Products to the Basket
-----------------------------
An important detail of the product template is providing the ability to add or remove a product to the basket.
This is done by making AJAX calls to the longclaw API.
2017-03-31 08:20:39 +00:00
In the product template, we would like to provide a means to select a variant and add it to the basket.
For t-shirts, our variants are going to represent different sizes, so we would like a single `` Add `` button
and a drop down of sizes.
We can acheive the drop down like this:
2017-03-30 20:52:59 +00:00
2017-03-31 08:20:39 +00:00
.. code-block:: django
2017-03-30 20:52:59 +00:00
2017-03-31 08:20:39 +00:00
<dl>
2017-04-05 13:32:22 +00:00
<dt>Format</dt>
2017-03-31 08:20:39 +00:00
<dd>
<div class="col-md-6">
<select id="variant-select">
{% for variant in page.variants.all %}
2017-04-05 13:32:22 +00:00
<option value="{{variant.id}}">{{variant.music_format}}</option>
2017-03-31 08:20:39 +00:00
{% endfor %}
</select>
</div>
</dd>
</dl>
2017-03-30 20:52:59 +00:00
2017-03-31 08:20:39 +00:00
Add a button:
2017-03-30 20:52:59 +00:00
2017-03-31 08:20:39 +00:00
.. code-block :: django
2017-03-30 20:52:59 +00:00
2017-03-31 08:20:39 +00:00
<button id="add-button">Add To Basket</button>
We can then write a jquery function to handle the click event:
.. code-block :: javascript
$('#add-button').click(function () {
// Selected variant
var variant_id = $('#variant-select option:selected').val();
// Add to the basket
$.post("api/add_to_basket/", { variant_id: variant_id });
});
This is a basic example of integrating with the basket. You will likely need to incorporate more
complex designs such as displaying a count of items in the basket, allowing the user to increase/decrease
quantity and so on. The :ref: `basket API <basket>` allows all such interactions and all front end design decisions such as these are left up to the developer