'Django Infinite dynamic Multi-level nested category

I have three models for now suppose one is category another is subcategory and another is product. Before registering a product user should add subcategory and before adding subcategory we need to add category in subcategory table. So, now adding a products need to be like Men's Fashion (Category)-> Shirt(SubCategory)-> White shirt(Product). It is working fine and I have no issue with it. But there is sudden changes like If I need to add infinite subcategory suppose there maybe some products like to go through two subcategory Men's Fashion(Category) -> Footwear(SubCategory) -> Shoe(SubCategory) -> Premium shoe (Product)

or maybe maybe some products like to go through two subcategory Men's Fashion(Category) -> Footwear(SubCategory) -> Shoe(SubCategory) -> Leather Shoe (Subcategory) -> Premium shoe (Product)

It will depend on the user he can add as many as subcategory he wants. This has to be like dynamic but I am wondering how. If I take multiple data and add model dynamically (I don't know if I can do this with django because the how can I sync the db without using migrate command) this is pretty much confusing me and I am stuck here. Any kind of help would be really appreciated.

class Category(models.Model):
   name = models.CharField(max_length=100)

class Subcategory(models.Model):
   name = models.CharField(max_length=100)
   category = models.ForeignKey(Category)

class Product(models.Model):
   name = models.CharField(max_length=100)
   subcategory = models.ForeignKey(Subcategory)


Solution 1:[1]

you can make the category reference optional and add an optional self referential foreign key on the sub category model:

class Subcategory(models.Model):
   name = models.CharField(max_length=100)
   category = models.ForeignKey(Category, blank=True, null=True)
   subcategory models.ForeignKey(Subcategory, blank=True, null=True)

now the subcategory can be pointed at a category OR at another subcategory, which provides infinite subcategory nesting.

alternatively, you can add some "level" property to the subcategory model:

class Subcategory(models.Model):
   name = models.CharField(max_length=100)
   category = models.ForeignKey(Category)
   level = models.IntegerField(default=0)

then you can have as many subcategories as you like pointing at a given category, and order them with the level field.

each approach has some pros and cons associated. the level property is less confusing and performs better, but the self reference is easier to manage.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1