Longclaw

Longclaw

  • Docs
  • Demo
  • Help

›Tutorial

Tutorial

  • Introduction
  • Setup
  • Adding Products
  • Shipping
  • Frontend
  • Payment

User Guide

  • Checkout
  • Integrations
  • Basket
  • API Client
  • Checkout API
  • Product Requests

Adding Products

Topics covered:

  • Creating the ProductIndex and ProductVariant model
  • Customising the models
  • Adding products via the admin

Initial Models

Longclaw makes as few assumptions as possible when it comes to modelling your products, since the requirements of different shops can be wide and varied.

You must create a ProductVariant model (it can be called anything) and implement a small number of fields Longclaw expects. The easiest way to do this is by inheriting from longclaw.products.ProductVariantBase.

Head over to catalog/models.py. You will see that longclaw created the following basic models for you:

  1. ProductIndex. This model is used for listings of products.
  2. Product. This is the model of a single product type. In our bakery, we might have a 'Farmhouse Loaf' product.
  3. ProductVariant. This model captures variations of a product. For example, we might offer our 'Farmhouse Loaf' using different flour types, different sizes, sliced or not sliced all for different prices. Note that it inherits from ProductVariantBase. This is important since there are small number of fields (such as price) that other longclaw packages expect to be present in order to function correctly.

This is just one way of modelling yor catalogue but you are not bound to it. ProductVariant is the only model required by Longclaw and precisely what this represents is up to your (e.g. it could be the product itself, or, as the name suggests, a variant of a product). You could create multiple 'index' pages, perhaps representing different lines aswell as multiple 'product' type pages, or do away with Product completely.

Customising

The ProductVariantBase model provides the base_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.

ProductVariant, Product and ProductIndex are all Wagtail Pages. If you are not familiar, it is important that you take a look at the Wagtail documentation before going further.

In our bakery, there are other product attributes we want to capture. We should add these to the ProductVariant model. Lets just consider a couple of basic fields:

  • Is it gluten free or not?
  • Suitable for vegetarians?

Lets adjust the ProductVariant model to reflect this:

class ProductVariant(ProductVariantBase):
    gluten_free = models.BooleanField(default=False)
    vegetarian = models.BooleanField(default=False)

Dynamic Pricing

The ProductVariant model can be configured so that the price is dynamically calculated. This is great - we can selectively apply a discount to our variants (or do anything else for that matter)!

The ProductVariant model provides a price property which is used throughout longclaw. By default, it simply returns the base_price attribute. We can override it to hold our custom price calculation.

For our bakery, I've decided that I want to be able enable a variable discount whenever we like.

So lets add a couple more fields to our model to provide the discount information:

   discount = models.BooleanField(default=False)
   discount_percent = models.PositiveSmallIntegerField(
     default=20,
     validators=[
            MaxValueValidator(75)
        ]
     )

Since I don't want to make mistakes and start offering my bread for free, I have limited the maximum discount to 75%. Finally, lets override the price getter to apply the discount:

@ProductVariantBase.price.getter
def price(self):
  if self.discount:
    discount_price = self.base_price * Decimal((100 - self.discount_percent) / 100.0 )
    return discount_price.quantize(Decimal('.01'), decimal.ROUND_HALF_UP)
  return self.base_price

Now, create and run the migrations for our catalog app:

python manage.py makemigrations catalog
python manage.py migrate

Further to the product models, the project template (created by longclaw start) also provided a ProductImage model. If you do not want an image(s) related to the Product model, delete this model and remove the InlinePanel line from the Product class. I leave it as an exercise to the reader to allow images at the ProductVariant level.

Using the Admin

The models are ready - Lets open up the admin and start adding our products.

Run the server:

python manage.py runserver

And navigate to localhost:8000/admin. You will need to sign in with the super user you created at the start of the tutorial.

Under 'Pages', select the root page:

Root page

On the 'Root' screen select 'Add Child Page' at the top. Here I selected my 'Home' page, but if you are running a small shop, you may wish your home page to be your product listing, in which case you might select 'Product Index'.

Adding a home page

We can now add Product models as children of ProductIndex. Only pages of type Product can be created under ProductIndex.

Adding a Product

Under the explorer homepage, we should now see our newly created ProductIndex. We can select Add child page to add our first Product. Add a title, description then start adding variants. You will see that in the product variants are the custom fields we added for applying discounts.

Image of the product

If we navigate back to the product index page, we see the new product listed:

Image of the product index

← SetupShipping →
  • Initial Models
  • Customising
    • Dynamic Pricing
  • Using the Admin
    • Adding a Product
Longclaw
Docs
Getting Started (or other categories)Guides (or other categories)API Reference (or other categories)
Community
User ShowcaseStack OverflowProject Chat
More
BlogGitHubStar
Copyright © 2019 James Ramm