longclawshop / longclaw

A shop for Wagtail CMS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to have multiple product variant models?

dinoperovic opened this issue · comments

Hi,

I have some trouble grasping the concept of modeling a catalog with different variant requirements.
How would one create a catalog with multiple ProductVariant models?

For example if I would have both mobile phones and t-shirts in a catalogue:

# Shirt product
class Shirt(ProductBase):
    description = RichTextField()
    # Other shirt fields

    content_panels = ProductBase.content_panels + [
        FieldPanel('description'),
        InlinePanel('variants', label='Product variants'),
    ]

class ShirtVariant(ProductVariantBase):
    COLORS = [('red', 'Red'), ('green', 'Green'), ('blue', 'Blue')]
    product = ParentalKey(Shirt, related_name='variants')
    shirt_color = models.CharField(choices=COLORS, default='blue')


# Phone product
class Phone(ProductBase):
    description = RichTextField()
    # Other phone fields

    content_panels = ProductBase.content_panels + [
        FieldPanel('description'),
        InlinePanel('variants', label='Product variants'),
    ]

class PhoneVariant(ProductVariantBase):
    CAPACITIES = [('32', '32 G'), ('64', '64 G'), ('128', '128 G')]
    product = ParentalKey(Phone, related_name='variants')
    phone_capacity = models.CharField(choices=CAPACITIES, default='32')

I have noticed that PRODUCT_VARIANT_MODEL setting is required, and I realise this is not the intended use of the ProductVariant model. Reading through the docs I've failed to understand how to achieve a similar catalog model.

Any explanation would be much appreciated. Thanks =)

@dinoperovic hello, did you succeded into multiple variant models ?

@tboulogne hi, I did not unfortunately :/

@tboulogne @dinoperovic I have plans to be spending some time around this in a couple of months once some obligations are cleared. Please share any progress you made here and your approach. What made the implementation difficult for you? Is there anything in particular that would ease your troubles?

@thenewguy, for my part no test. Trying now saleor with this feature. But saleor is heavy... :-)

@thenewguy Hi!

Maybe consider a product on basket and order models to be implemented as a generic relation?
Similar to: https://github.com/bmentges/django-cart/blob/master/cart/models.py

You would have to allow users to then configure which product types are allowed and their respected serializers.

In this case when adding a product to basket user would have to specify both the product_id and product_type in the request.

This could be required only in a case that multiple product types are defined.

Just a thought.

@tboulogne give django-shop a try. :)

Having re-read the initial question, I think this is just a case of making your variant models more dynamic.

There isn't any difference between a Shirt product and a Phone in how you have defined it, so we can keep the standard product class:

class Product(ProductBase):
    description = RichTextField()

    content_panels = ProductBase.content_panels + [
        FieldPanel('description'),
        InlinePanel('variants', label='Product variants'),
    ]

we might want to enrich it with a 'category' field.

Now we want a variant model, where we can choose what we use for the 'choices'. Django has something builtin for that - the ModelChoiceField

class ProductVariant(ProductVariantBase):

   product = ParentalKey(Product, related_name='variants')
   property_name = models.CharField(...)
   property_model = models.ModelChoiceField(...)

We can then make any number of separate models for different types of variants.
The idea is to make the product/variant as generic and configurable as possible (balanced against ease of use) so that when you have a new product type you can just add it in the admin.

Hey @JamesRamm thank you for the example.

I guess its my fault for not giving a more full example but the idea was that both the base product and variant for phone and shirt would have much different fields (hence the comment # Other phone fields).

While many of the fields/values could be implemented as some sort of generic flags, and also variant choices could be set-up using some sort of attribute-entity-value pattern, what I was trying to achieve is a cleaner way of modeling such a catalog so that filtering and searching by product variants could be done without much db queries later.

I understand this would be an issue only with very complex catalogs, but that is sometimes what my projects require.

Reading through the docs I've gotten the impression this was the intended way of modeling a catalog.

I appreciate the help! :)

Some more thoughts;
You can go even more generic than what I posted above. There is a very relevant post on the wagtail users group here:
https://groups.google.com/forum/#!topic/wagtail/TP8WAQpenlc

The overall point however is that 90% of the time, I think you should be trying to avoid making multiple, product-specific models, as it prevents admins from simply adding new products via the admin page(s).
For your specific use case, there are a few different routes you could take, as shown.

The overall point however is that 90% of the time, I think you should be trying to avoid making multiple, product-specific models, as it prevents admins from simply adding new products via the admin page(s).

I thought the point of Wagtail was to build custom page types that can then be added via admin. Why shouldn't that be the case with product types as well? I don't see how it prevents admins from adding a product and selecting it's type (page type from wagtail). 🤔

Anyway I don't wish to waste your time any further.. I'm not insisting on implementing such a feature, just wanted to get some insight.

Thanks!