2👍
You could consider to use django-polymorphic.
If you do this, just let Resource inherit from PolymorphicModel like this:
from polymorphic.models import PolymorphicModel
class Supplier(models.Model):
delivery_time = models.CharField(max_length=255, blank=True, null=True)
minimum_order_quantity = models.FloatField(blank=True, null=True)
class Resource(PolymorphicModel):
code = models.CharField(max_length=255, unique=True, blank=True, null=True)
country = models.CharField(max_length=255, blank=True, null=True)
class Part(Resource):
some_attr = models.CharField(max_length=255, blank=True, null=True)
class Fuel(Resource):
some_other_attr = models.CharField(max_length=255, blank=True, null=True)
And then you can create the SupplierResource model like the following:
class SupplierResource(models.Model):
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
resource = models.ForeignKey(Resource, on_delete=models.CASCADE)
Or, a many to many relations between Supplier and Resource:
class Supplier(models.Model):
delivery_time = models.CharField(max_length=255, blank=True, null=True)
minimum_order_quantity = models.FloatField(blank=True, null=True)
resources = models.ManyToManyField(Resource, related_name="suppliers")
1👍
As mentioned by C14L you can use a GenericForeignKey to create a relationship with another model. However GenericForeignKeys come with their own issues. They don’t create reverse relationships. So you wouldn’t be able to do, for example, [sr.supplier for sr in Part.supplier_resources]
, however it would allow you to get rid of your Resource
parent model. What you’ve got with the Resource parent model is the right idea I believe. I would suggest in the
resource model, you add a field a field called child_model_name
class Resource(models.Model):
child_model_name = models.TextField()
some_attr = models.CharField(max_length=255, blank=True, null=True)
where child_model_name = 'part'
etc..
Then in your SupplierResource Model you have
class SupplierResource(models.Model):
supplier = models.ForeignKey(Supplier, ..., related_name="supplier_resources")
resource = models.ForeignKey(Resource, ..., related_name="supplier_resources")
Here what django is doing for you is creating a table called Resource
that contains all the fields for a Resource. It also creates a table for you called Part with fields specific to a part that has a OneToOne relationship to Resource.
Now can you do this:
parts = Part.objects.filter(supplier_rescources__supplier=supplier)
Or to get different types of resource in one list (Part, fuel etc).
resources = Resource.objects.filter(supplier_resources__supplier=supplier)
[getattr(resource, resource.child_model_name) for resource in resources]
0👍
Could you use Generic Foreign Keys? They use content_type
and object_id
to map the same field to different models:
https://docs.djangoproject.com/en/4.0/ref/contrib/contenttypes/#generic-relations
- [Django]-Retrieve the integer stored in (?P<topic_id>\d+)
- [Django]-What happens during AWS Elastic Beanstalk 504 Gateway Timeout
- [Django]-Django DetailView failing to find object based on SLUG