2012-03-14 83 views
1

我在我的一个Django应用程序中有一个图像字段,但希望能够存储图像的修订,以便允许我按修订顺序显示列表。最好的方法是单独存储图像,然后与父母图像建立“父”外键关系?例如:亲子关系效率

class Image(models.Model): 
    name = models.CharField(max_length=50) 
    parent = models.ForeignKey(Image, null=True) 
    image = models.ImageField(upload_to='images') 

如果没有父(null=True),则图像必须没有修改。每个对象只能有一个父级和一个子级,但层数可能是无限的。

我不知道是否可以遍历多个子层,而不会生成大量的SQL查询,这会使应用程序非常低效。用Django对象表示这个最好的方法是什么?例如,为了处理图层,有一个单独的“ImageRevision”对象会更好吗?

感谢

回答

1

我看到两种方法可以有效地做到这一点:

  1. 领带Image到它的使用在模型上,允许一个一对多的图像:

    class Image(models.Model): 
        obj = models.ForeignKey(MyModel, related_name='images') 
        name = models.CharField(max_length=50) 
        image = models.ImageField(upload_to='images') 
        created = models.DateTimeField(auto_now_add=True) 
    
        class Meta: 
         ordering = ['-created'] 
         get_latest_by = 'created' 
    

    然后你可以通过这样做得到最新版本:

    my_model_instance.images.latest() 
    
  2. 创建一个ImageRevision模型,如您所说,并将其绑定到Image

    class Image(models.Model): 
        name = models.CharField(max_length=50) 
    
    class ImageRevision(models.Model): 
        parent = models.ForeignKey(Image, related_name='revisions') 
        image = models.ImageField(upload_to='images') 
        created = models.DateTimeField(auto_now_add=True) 
    
        class Meta: 
         ordering = ['-created'] 
         get_latest_by = 'created' 
    

    然后,你可以得到最新的版本:

    my_model_instance.image.revisions.latest() 
    

第二种方法是为更多的关系,其他查询(虽然你应该能够减轻,如果使用得当的select_related),但具有可以与多种不同型号一起使用的优点,而第一种方法将内在地与Image绑定到一个型号。

+0

感谢您的全面,真正有用的解释! – jvc26 2012-03-14 17:45:28

0

我可能会在这种情况下,要做的就是去与不同的对象的修订。从图像中删除父字段(顺便说一下,它将是一个OneToOne,而不是一个ForeignKey,以防止来自单个父级的多个子级)。所以,你有一个名字一个Image对象,并用ImageField的修订对象,像这样:

class Image(models.Model): 
    name = models.CharField(max_length=50) 
    def __unicode__(self): 
     return self.name 

class Revision(models.Model): 
    image = models.ForeignKey(Image) 
    revision_number = models.IntegerField() 
    file = models.ImageField(upload_to='images') 

横移,然后不通过链条需要递归。像这样:

for i in Image.objects.all(): 
    print i.name 
    for r in Revision.objects.filter(image=i).order_by('revision_number'): 
     print "rev. " + str(r.revision_number) + " " str(r.file) 

这就是我至少会处理它。

干杯