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 toAssembly
component
- ForeignKey toComponent
quantity
- IntegerField
Make another model AssemblyAssembly
with the fields
assembly_parent
- ForeignKey toAssembly
assembly_child
- ForeignKey toAssembly
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.
- For more about inline admins, see: https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#inlinemodeladmin-objects
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.