Query using polymorphism

Hi,

I read a lot of stuff about how using polymorphism but I can’t find my one into this.

I have 3 models:

Parent models

class Marker(models.Model):
    latitude = models.FloatField(blank=False)
    longitude = models.FloatField(blank=False)
    note = models.TextField(verbose_name='note', blank=True, null=True)
    related_client = models.ForeignKey(Ville, on_delete=models.CASCADE)



    def __str__(self):
        return 

    def __unicode__(self):
        return 

and 2 child:

child 1 :

class EntreeEau(Marker):
    
    identification = models.CharField(max_length=30, blank=False, unique=True)  # La validation ne sera pas la meme que Commerciale
    type = models.IntegerField(default=EE_Type.RESIDENTIEL, choices=EE_Type)
    related_adresse = models.ForeignKey(CivicAdresse, on_delete=models.SET_NULL, null=True, blank=True)
    dimension = models.IntegerField(default=EE_Dimension._3_4po, choices=EE_Dimension)
    mat_type = models.IntegerField(default=EE_Mat_type.CUIVRE, choices=EE_Mat_type)

    def label(self):
        return self.type.label

    def __str__(self):
        return self.identification

    def __unicode__(self):
        return self.identification
    
    class Meta:
        verbose_name = "Entree d'eau"
        verbose_name_plural = "Entre d'eau"

child 2:

class Travaux(Marker):
    description = models.TextField(blank=False)
    date_added = models.DateTimeField(auto_now_add=True)
    date_start = models.DateField()
    date_end = models.DateField()
    added_by_user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)

I want query all Marker of type EntreEau for instance.

Can anyone help me please ?

Should we use extra manager like django-models-utils ? or does by default it’s supposed to be possible ?

In this case I think you can simply do

Marker.objects.filter(entreeeau__isnull=False)

most of the polymorphism tooling is to support returning different model types from the same queryset. If you don’t need that you can stick to what the ORM provides by default.

I will expend the subclasses list to maybe 4-5 type of Marker. Is there something more convenient ?

I know I can join table, also do raw query. But just trying to figure out the most effective way to work it.

Can you elaborate on what’s inconvenient about the above?

I’d mean, for the example I giving only 2 subclass by actually I have 8 subclass. .filter(entreeau_isnull=False).filter(anothertype_isnull=False)… is the way to do.

All subclass object have a ptr to the parent model objects. Can we reverse search it ?

All subclass object have a ptr to the parent model objects. Can we reverse search it ?

yes at a cost of one LEFT OUTER JOIN per by iterating over Marker._meta.related_objects, identifying all parent links, and turning it into a filter(Q(child0__isnull=False) | ... | Q(childn__isnull=False)).

If you don’t want to get into this business relying on third-party polymorphic model solution might be worth doing. What they usually do is keep a ForeignKey(ContentType) at the root model level that is persisted at save time of children to denormalize the data so the JOINs are not necessary at querying time.

OK thank you. I will check this out.