2012-07-17 22 views
6

私は中間モデル(キーワードを介して)(https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships)私はジャンゴtastypie:中間モデル

を使用して多対多の関係でTastypieを使用しようとしているを使用してM2M関係の余分な値を取得しますこれらのモデルでの作業:

class Point(models.Model): 
    ... 
    value = models.FloatField(_('Value'), null=True) 
    rooms = models.ManyToManyField('rooms.Room', through='points.PointPosition') 

class Room(models.Model): 
    title = models.CharField(max_length=64) 

class PointPosition(models.Model): 
    point = models.ForeignKey('points.Point', verbose_name=_('Point')) 
    room = models.ForeignKey('rooms.Room', verbose_name=_('Room')) 
    x = models.IntegerField(_('Y')) 
    y = models.IntegerField(_('X')) 

私は多対多の関係を取得することができましたが、ない余分なフィールド 。ここに私のtastypieコードです:私はこのように私のPointResource水和物部屋変数にメソッドを使用しようとしてきた

class PointResource(ModelResource): 
    class Meta: 
     queryset = Point.objects.select_related(
      depth=10 
      ).prefetch_related('rooms').all() 
     resource_name = 'point' 
     allowed_methods = ['get'] 

    ... 
    value = fields.FloatField() 
    rooms = fields.ToManyField('rooms.api.RoomResource', 'rooms', full=True) 

class RoomResource(ModelResource): 
    class Meta: 
     queryset = Room.objects.all() 
     resource_name = 'room' 
     allowed_methods = ['get'] 

def dehydrate_rooms(self, bundle):                                                       
    rooms = []                                                            
    for room in bundle.obj.rooms.all():                                                      
     position = PointPosition.objects.get(                                                    
      room_id = room.pk,                                                        
      point_id = bundle.obj.pk)                                                            
     rooms.append({'id': room.pk,                                                         
      'title': room.title,                                                       
      'x': position.x,                                                        
      'y': position.y})                                                            
    return rooms 

しかし、問題は、それが作成することです私が指摘しているものと同じくらいたくさんの質問があります。あなたが+8000ポイントを持っているときはパフォーマンスキラーです。

私はパフォーマンスを得るために有用なリソースを見つけることができませんでした。 私はQuerySetで利用可能な.extra()メソッドを使ってカスタムクエリを行うことを考えていましたが、JOINキーワードは利用できません(パッチは数ヶ月前に拒否されています)。 SELECTサブクエリがこのトリックを行うかどうかはわかりません。

答えて

7

PointPositionリソースを使用するようにクエリセットを変更することを検討しましたか?で

class PointResource(ModelResource): 
    class Meta: 
     queryset = PointPosition.objects.select_related("point", "room") 
     resource_name = 'point' 
     allowed_methods = ('get',) 

:「ポイント」は、あなたのデータベースに何を意味するのか、それの音から、実際に内部の詳細を隠すために、いくつかの翻訳が必要であるので、「ポイント」は、あなたのAPIに何を意味するかと同じではありませんフィルタリングパラメータを調整する必要があるため、複数のクエリを実行する必要はありません。 dehydrateメソッドを使用すると、必要に応じてデータをスワップできます。 .values()を使用すると、一部のオーバーヘッドを省くだけで、完全なオブジェクトではなく、必要なフィールドを辞書として引き出すこともできます。

+0

お返事ありがとうございます。 これは実際に私がやったことですが、要素を交換して辞書を並べ替えるために「脱水」を使用するとは思いませんでした。クールなヒント: – Solvik

+1

私は自分に単純なデータ構造を構築していることを思い出させる前にtastypieと戦うのに時間がかかり過ぎ、辞書を作る正しい方法は一つもありませんでした。私は少なくとも1つのリソースを持っています。そこでは、ぎこちないオーバーライドされたModelResourceが、複雑なデータ構造を効率的に構築するために単純にORMを直接呼び出す単純なリソースになりました。 –

関連する問題