Modelling your catalogue¶
Oscar gives you several layers of modelling your products.
Note that this document is merely concerned with how to model products in your database. How you display them in your front-end, e.g. in a category tree, is out of scope.
Product classes¶
Typical examples for product classes would be: T-shirts, Books, Downloadable products.
Each product is assigned to exactly one product class.
Settings on a product class decide whether stock levels are
tracked
for the associated products, and whether they
require shipping
.
Furthermore, they govern what kind of product attributes can be stored on the products. We’ll get to attributes in a bit, but think T-shirt sizes, colour, number of pages, etc.
Typically stores will have between 1 and maybe 5 product classes.
Product attributes¶
Product attributes let you set additional data on a product without having
to customise the underlying Django models. There’s different types of
attributes, e.g. ones for just associating text (type text
or richtext
),
for related images and files (type image
and file
), etc.
Storing data in structured attributes also makes it easy to search and filter products based on specific attributes.
The available product attributes for a product are set when creating the
product’s class. The sandbox comes with a product class for T-shirts, and
they have a size
attribute:
> shirt = Product.objects.filter(product_class__slug='t-shirt').first()
> shirt.attr.size
<AttributeOption: Large>
You can assign option
s to your product. For example you want a Language attribute
to your product, and a couple of options to choose from, for example English and
Croatian. You’d first create an AttributeOptionGroup
that would contain all the
AttributeOption
s you want to have available:
> language = AttributeOptionGroup.objects.create(name='Language')
Assign a couple of options to the Language options group:
> AttributeOption.objects.create(
> group=language,
> option='English'
> )
> AttributeOption.objects.create(
> group=language,
> option='Croatian'
> )
Finally assign the Language options group to your product as an attribute:
> klass = ProductClass.objects.create(name='foo', slug='bar')
> ProductAttribute.objects.create(
> product_class=klass,
> name='Language',
> code='language',
> type='option',
> option_group=language
> )
You can go as far as associating arbitrary models with it. Use the entity
type:
> klass = ProductClass.objects.create(name='foo', slug='bar')
> ProductAttribute.objects.create(
product_class=klass, name='admin user', code='admin_user', type='entity')
<ProductAttribute: admin user>
> p = Product(product_class=klass)
> p.attr.admin_user = User.objects.first()
> p.save()
> p.attr.admin_user
<User: superuser>
You can also use the multi_option
attribute type if your options are not
mutually exclusive:
> klass = ProductClass.objects.create(name='foo', slug='bar')
> ProductAttribute.objects.create(
> product_class=klass,
> name='Size',
> code='size',
> type='multi_option',
> option_group=language
> )
This will let you assign multiple values (size
in the example above) to the
attribute.
You can also query for attributes using a special method on the manager:
> first_large_shirt = Product.objects.filter_by_attributes(size="Large").first()
> first_large_shirt.attr.size
<AttributeOption: Large>
All attribute types apart from entity
can be edited in the product
dashboard. The latter is too dependent on your use case and you will need to
decide yourself how you want to set and display it.
Variants (Parent and child products)¶
Often there’s an overarching product, which groups other products. In that
case, you can create a parent product, and then set the parent
field on the
child products. By default, only parent products (or products without children)
get their own URL.
Child products inherit their product class from the parent, and only child
products can have stock records (read: pricing information) on them.
Product attributes vs. variants¶
When to use variants, and when to use attributes?
Variants are tied to stock records, and hence, pricing. Use variants if your product variations have different pricing or availability.
Use attributes when you are storing structured data for a product (i.e. colour, size) that you can use for search/filtering/display purposes.
Going further¶
Oscar’s modelling options don’t stop there. If the existing framework does not
suit your need, you can always customise
any involved models. E.g. the Product
model is often customised!