[Django]-Django Differentiating Children in Queryset

3👍

You can use Content Types on the Parent model if you did not know the name of the class you wanted to get. For example:

(not tested)

from django.contrib.contenttypes.models import ContentType

class Block(models.Model):
   zone = models.ForeignKey(Zone)
   order = models.IntegerField()
   weight = models.IntegerField()
   block_type = models.ForeignKey(ContentType, editable=False)

   def save(self, *args, **kwargs):
        if not self.id:
            self.block_type = self._block_type()
        super(Block, self).save(*args, **kwargs)

   def __block_type(self):
        return ContentType.objects.get_for_model(type(self))

    def cast(self):
        return self.block_type.get_object_for_this_type(pk=self.pk)

    class Meta:
        abstract = True

Also note the abstract base class this means the model won’t be created in the database. The abstract fields will be added to those of the child class i.e.

class TextBlock(Block):
    content = models.TextField(blank=True)

However, you can’t query the abstract base class in this example. If this is what you want to do then simple add a lookup on your base class.

 TEXT = 'TXT'
 IMAGE = 'IMG'
 VIDEO = 'VID'
 BLOCK_CHOICES = (
        (TEXT, 'Text Block'),
        (IMAGE, 'Image Block'),
        (VIDEO, 'Video Block'),
    )

class Block(models.Model):
    zone = models.ForeignKey(Zone)
    order = models.IntegerField()
    weight = models.IntegerField()
    block_type = models.CharField(max_length=3, choices=BLOCK_CHOICES)

Then query: Block.objects.filter(block_type='Text Block')

Or in your example:

blockset = Block.objects.all()
for block in blockset:
    if block.block_type == "Text Block":
        print("This is a text block!")

Leave a comment