Reputation: 4008
I have two models Category and Products.
Example:
models.py
class Product:
categories = models.ManyToManyField(Category)
name = models.CharField(max_length=255)
class Category:
categories = models.ForeignKey(self)
name = models.CharField(max_length=255)
As Form I use a ModelForm:
class ProductForm(ModelForm):
class Meta:
model = Product
fields = ['categories', 'name', 'short_description', 'description']
widgets = {
'categories': MyWidget,
}
What I want to achieve:
I want to implement a conditional select (narrow options) On Product Form creation:
The user select a level 1 Category (A1,C1). If the parent has children a new Select box appear with his children(level 2 A2)
Options I thought:
Practical, let's say I have 7 Select Boxes, with the values for each:
How do I tell Django on browser submit(with other data) to send to ManyToMany the last Child in all three of them
I can gather them with Javascript, but I have to tell Django get this data, this is what you need.
I need some help as code and indication how to do this.
Upvotes: 5
Views: 1248
Reputation: 1745
Django allows you to define the model you are referencing in a ForeignKey
or ManyToManyField
as an '<app_name>.<model_name>'
string instead of having to import the model and directly assigning it. This resolves a lot of issues, especially circular imports.
Assuming you have the apps categories
with a Category
model and products
with a Product
model, this:
products/models.py
:
class Product:
categories = models.ManyToManyField(Category)
name = models.CharField(max_length=255)
categories/models.py
:
class Category:
categories = models.ManyToManyField(self)
name = models.CharField(max_length=255)
can directly translate to what you need:
products/models.py
:
class Product:
categories = models.ManyToManyField('categories.Category')
name = models.CharField(max_length=255)
categories/models.py
:
class Category:
categories = models.ManyToManyField('self')
name = models.CharField(max_length=255)
With this, you can have as many categories as you want:
category_one = Category.create(name='Category one')
category_two = Category.create(name='Category two')
category_three = Category.create(name='Category three')
category_three.categories.add(category_one, category_two)
some_product = Product.create(name='Test Product')
some_product.categories.add(category_three)
It is also important to note that with any Python class, self
isn't the class itself – it's the instance. So you can't reference it outside of an instance method, there's a good explanation on why here. The only reason the 'self'
string works here is because Django translates that to the class it's within, categories.Category
–– so it might be a good idea to replace self
with 'categories.Category'
to be explicit.
Upvotes: 2