Reputation: 143
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
Upvotes: 0
Views: 108
Reputation: 136
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.
Upvotes: 0
Reputation: 141
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
- IntegerFieldMake another model AssemblyAssembly
with the fields
assembly_parent
- ForeignKey to Assembly
assembly_child
- ForeignKey to Assembly
quantity
- IntegerFieldYou 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.
Upvotes: 2