I'm writing an app for creating sales quotes. The quote consists of one or more lineitems. Each lineitem consists of a product and some product-specific properties. The user should be able to input the products they want to sell and the properties associated with it at runtime.
For example, the user might decide they're selling cars (properties: colour, air conditioning) and tomatoes (properties: weight).
When the user creates a lineitem, I want them to choose a product (a car or tomato or any other products they've added) and the properties for that lineitem. For example, they may want to include a red car with air-conditioning, a blue-car without air-conditioning, and a 0.25 kilogram tomato.
I've found JSONFields allow one to add multiple properties on the fly. The challenge is accessing those properties from the lineitem.
I've set up the models
from django.db import models
# Create your models here.
class Product(models.Model):
product_name = models.TextField()
specs = models.JSONField()
class LineItem(models.Model):
product_type = models.ForeignKey(Product, on_delete=models.CASCADE)
specs = models.JSONField()
and the views to create products or lineitems:
class CreateLineItemView(generic.CreateView):
model = LineItem
fields = ["product_type", "specs"]
template_name_suffix = "_create_form"
def get_success_url(self):
return reverse('poc:index')
class CreateProductView(generic.CreateView):
model = Product
fields = ["product_name", "specs"]
template_name_suffix = "_create_form"
def get_success_url(self):
return reverse('poc:index')
My ideal solution: On the form for creating the lineitem, you'd select a product. Each spec associated with the product would then appear on the form, each having its own widget.
One option I've considered is using a multi-page form for the lineitem. In the first page of the form, the user would choose the product type and save the record with null values for specs. Then the second page of the form would initialize the specs field of the lineitem with a copy of the specs field from the product. I don't love this because 1) it means I have to set the database to allow null values for specs. 2) I'd like to have everything on the same form page. 3) there's a single field for all specs. My user would have to enter JSON to describe, e.g. colour and air-conditioning. That's not very user friendly.
Is the ideal solution possible? If not, is there a single-page approach? How can I avoid forcing the user to enter JSON?