Home > Net >  Django ManyToMany with quantity
Django ManyToMany with quantity

Time:07-19

I'm having a bit of a problem trying to model something in Django that I've conceptualized. I know that it is a many to many relationship... however it is sort of self referential and has a quantity involved. I imagine this requires a bridge model of some sort, which I have, but now how do I edit them in the admin page?

What I have is a Component class. For example, a 'screw' is a component, and it requires no further components to create it. But so is a 'housing', which requires 4 screws to hold it together. That housing could then go into a manifold and the manifold could go into a vehicle and so forth.

Each thing could potentially be a component of another thing if that makes sense. I've put all of the screws and bolts and such into the database through the admin edit page. But now I want to start putting in more complex assemblies. I could just create an Assembly class which has a list of one or more components. But I'm still left with the problem that this assembly could go into a larger assembly zero or more times.

How do I represent that?

currently I have

class ComponentBase(models.Model)
   name = models.CharField(max_length=255)

   class Meta:
     abstract = True
     ordering = ['name']


class ItemComponent(ComponentBase):
   components = models.ManyToManyField('ItemComponentWithQuantity', blank=True)



class ItemComponentWithQuantity(ItemComponent):
   quantity = models.IntegerField(default=1)

assuming this is the correct way to model this (is it?) how do I get the admin edit form to set this up a bit like a spreadsheet or list?

like

name: manifold assembly
components:
   10x screws
   10x bolts
   1x assembly housing

The components field should only show the ones that have been added and the quantity. Not all possible components.

i had my model originally set up to have components = models.ManyToManyField('ItemComponent', blank=True). This caused the admin panel to have a list of all the existing ItemComponents as expected, but obviously no quantities.

Adding the ItemComponentWithQuantity class in, I changed the manytomanyfield to ItemComponentWithQuantity. But now the admin components field is empty.

I hope I'm making sense here. I'm not sure what I'm doing incorrectly.

thanks in advance. EK

CodePudding user response:

The inheritance that you're doing is making this too complicated. You can model this a different way. Change your ComponentBase to a basic model.Model (not abstract) named Assembly. Change ItemComponent to just Component. Lastly change your ItemComponentWithQuantity to AssemblyComponent.

The AssemblyComponent should have the fields

  • assembly - ForeignKey to Assembly
  • component - ForeignKey to Component
  • quantity - IntegerField

Make another model AssemblyAssembly with the fields

  • assembly_parent - ForeignKey to Assembly
  • assembly_child - ForeignKey to Assembly
  • quantity - IntegerField

You would then create either a Tabular or Stacked inline admin (depends on desired user experience) for both AssemblyComponent and AssemblyAssembly. Be sure to set fk_name in the AssemblyAssembly to point to the assembly_parent as the fk_name because you have two foreign key fields referencing the same model. You can use a raw_id_field for the assembly_child if there will be a lot of possible assemblies in the system. Use the inline admins for the Assembly admin.

That will give you roughly the admin UI that you want with the exception that component and assembly links will be in separate inline admins.

CodePudding user response:

For this you can just have a single model and make it a recursive model where it is in a relationship with itself

component = models.ForeignKey('self', on_delete=models.CASCADE)

i also advice you add an extra field for quantity instead of creating a whole model for that. Hope this works.

  • Related