2012-03-14 17 views
1

私は私のDjangoアプリケーションの1つに画像フィールドを持っていますが、画像のリビジョンを保存してリビジョン順にリストを表示できるようにしたいと考えています。画像を別々に保存し、親画像に「親」ForeignKey関係を持たせるために、これを行う最善の方法はありますか?たとえば、次のように親子関係の効率

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

親(null=True)その後、画像が何のリビジョンを持っていない必要がありますがない場合。各オブジェクトには親と子がそれぞれ1つしかありませんが、レイヤーの数には制限がありません。

子どもの複数のレイヤーが、かなりの数のSQLクエリを生成せずにトラバースできるかどうかはわかりません。これは、アプリを非常に非効率にします。これをDjangoオブジェクトの観点から表現する最良の方法は何ですか?例えば、レイヤーを扱うために、別々の 'ImageRevision'オブジェクトを持つ方が良いでしょうか?私はおそらくこのような場合にはどうなるのか

おかげ

答えて

1

私はこれを効率的に行うには、2つの方法を参照してくださいできるように、それが使われているモデルに

  1. タイImageを1対多のイメージのために:

    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に結び付けます。あなたは慎重に使用してそれを軽減することができるはずですけれども(第2の方法は、追加的な関係のために追加のクエリを必要とする

    my_model_instance.image.revisions.latest() 
    

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' 

次に、あなたが最新のリビジョンを取得することができますselect_related)、複数の異なるモデルで使用できるという利点がありますが、最初の方法ではImageが本質的に1つのモデルに結びついています。

+0

包括的で本当に役立つ説明をありがとう! – jvc26

0

は別のリビジョンの対象と行くです。単一の親から複数の子を防ぐために、親フィールドをImageから削除します(脇に、ForeignKeyではなくOneToOneです)。その後、チェーンを通じて、再帰を必要としない、

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') 

トラバース:だから、あなたは、このような名前を持つImageオブジェクト、およびのImageFieldとリビジョンオブジェクトを、持っていると思います。このようなもの:

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) 

これは、少なくとも私がそれを処理する方法です。

乾杯

関連する問題