2015-02-09 40 views
3

我有一個名爲「阻止」Django的辨兒童的QuerySet

class Block(models.Model): 
zone = models.ForeignKey(Zone) 
order = models.IntegerField() 
weight = models.IntegerField() 
block_type = models.CharField(max_length=32, blank=True) 

class Meta: 
    ordering = ['order'] 

def __str__(self): 
    return "Block "+str(self.order) 

的塊對象有孩子從它繼承模式。 ImageBlock,VideoBlock等...隨着項目的推進,我將增加更多

# Children of Block Object 
class TextBlock(Block): 
    content = models.TextField(blank=True) 

class ImageBlock(Block): 
    content = models.ImageField(blank=True) 

class VideoBlock(Block): 
    content = models.FileField(blank=True) 

我需要根據它們的順序對塊執行操作。如,

渲染TextBlock1 渲染ImageBlock1 渲染TextBlock2

我查詢了所有這些對象連同Block.objects.all()線的東西,然後遍歷它們。當我這樣做時,我該如何區分每個對象的哪些對象?

如:

blockset = Block.objects.all() 
for block in blockset: 
    if (**some way of differentiating if it's a TextBlock**): 
     print("This is a text block!") 

的我怎麼會去這樣做的任何想法?

非常感謝!

+0

什麼''block_type''?你不使用它來確定類型嗎? – 2015-02-09 22:18:25

+0

這可能比您需要的更多或更少,但您可能對django_model_utils pacakge感興趣,以便您可以執行諸如[this]之類的操作(https://django-model-utils.readthedocs.org/en/latest/managers.html #inheritancemanager)。 – 2015-02-09 22:39:53

回答

3

如果您不知道要獲取的課程名稱,則可以在Parent模型上使用Content Types。例如:

(未測試)

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 

還要注意的抽象基類,這意味着該模型將不會在數據庫中創建。抽象字段將被添加到子類的那些字段中,即

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

但是,在本例中不能查詢抽象基類。如果這是你想要做的事情,那麼簡單地在你的基類中添加一個查找。

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) 

然後查詢:Block.objects.filter(block_type='Text Block')

或者在你的榜樣:

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

嗯是的我一直希望擺脫基礎對象的block_type字段,但你說得對,我無法查詢一個抽象類(沒有這一點,ContentType只是返回我的父塊對象的名稱。) 無論如何,感謝您的澄清,並介紹我的內容類型功能! – 2015-02-10 14:34:17

+0

不是問題,我希望它有幫助。 – 2015-02-11 10:49:27