Django formset with nested single inline form of each formset object(form)
I'm trying to figure out the logic of building such structure:
class Order(models.Model):
id = ...
class OrderItem(models.Model):
order = FK(Order)
quantity = CharField()
category = CharField(choices=..)
class OrderItemSchema(models.Model):
class Meta:
abstract = True
order_item = OneToOneField(OrderItem)
brand = CharField()
model = CharField()
class SomeProduct1Schema(OrderItemSchema):
size = PositivieIntegerField()
class SomeProduct2Schema(OrderItemSchema):
weight = CharField()
type = CharField()
Let's assume some customer has created new Order
which "Company" has to produce. There are different types of products (not much: 2-10) which may not have even single common parameter/field but still be placed withing one Order
.
The question is:
How to manage FormSet (or there is another way?) of OrderItem
elements where each element may has different fields?
Example:
OrderItem
: [SomeProduct1Schema
] \ category \ quantity \ brand \ model \ sizeOrderItem
: [SomeProduct2Schema
] \ category \ quantity \ brand \ model \ weight \ type
So far I've added OrderItem
inline formset to Order
and both SomeProduct1Schema
\ SomeProduct2Schema
inline formsets attached to OrderItemFormSet
as nested form. But it's works well with single nested formset class and becoming mess when need to handle multiple dynamically.
Now I'm thinking to make SomeProduct1Schema
classes to inherit from OrderItem
directly using multi-table inheritance.
Performance is not a problem in this case as scalability is prefered. Appreciate any advice.
I think for this case django BaseFormSet might do the trick for example as you can see Django BaseFormset can able to help you to do fill up mutliple model instances at single go, Read the django docs about more, you will get the idea of it.Below is just a
class SomeProduct1Form(OrderItemForm):
size = forms.IntegerField()
class SomeProduct2Form(OrderItemForm):
weight = forms.CharField()
type = forms.CharField()
# Custom FormSet
class CustomOrderItemFormSet(BaseFormSet):
def add_fields(self, form, index):
super().add_fields(form, index)
# add product-specific fields
if form.instance.category == 'foo':
form.fields['size'] = forms.IntegerField()
elif form.instance.category == 'foo2':
form.fields['weight'] = forms.CharField()
form.fields['type'] = forms.CharField()
# Create a formset factory
OrderItemFormSet = formset_factory(OrderItemForm, formset=CustomOrderItemFormSet)