Single 'through' model for multiple m2m fields
I'm trying to extend and refactor some legacy project. I have some set of models which represent "hardware" of some assebled device. Something like :
class ComponentA(models.Model)
brand = models.CharField()
model = models.CharField()
category = models.ForeignKey(Category)
class Configuration(models.Model):
component_a = ForeignKey(ComponentA)
component_b = ForeignKey(ComponentB)
component_n...
class Device(models.Model):
configuration = models.ForeignKey(Configuration)
The goal is to extent ComponentA...ComponentN
with Many2Many
field which suppose to contain some extra parts and those parts quantity it consist of. However I found it weird to have through
model for each Component
model. All of the Component
models shoud have a quantity for further statistic/calculations.
Is there is some "clean" approach for implementation such a functionality?
The model ComponentListing
allows you to add a quantity for each item of a configuration. The Configuration
now can hold an arbitrarily chosen amount of Components
through ComponentsListing
which adds said quantity to it.
Spend some thought how you want to set up the on_delete
functionality.
# models.py
class Component(models.Model):
brand = models.CharField(max_length=XXX)
model = models.CharField(max_length=XXX)
category = models.ForeignKey(Category, on_delete=models.XXX)
class ComponentListing(models.Model):
component = models.ForeignKey(Component, on_delete=models.XXX, related_name='listings')
quantity = models.IntegerField()
configuration = models.ForeignKey('Configuration', on_delete=models.XXX, related_name='component_listings')
def __str__(self):
return f"{self.component} - {self.quantity}"
class Configuration(models.Model):
# no field required
class Device(models.Model):
configuration = models.ForeignKey(Configuration, on_delete=models.XXX)
# python manage.py shell
d = Device.objects.get(id=XXX)
for listing in d.configuration.component_listings.all():
print(listing)
print(listing.quantity)
print(listing.component.model)
print(listing.component.category.XXX)