Django では、多対多の関係を持つリソースを要求すると、親に直接関係していないものも含め、関係の子部分のすべての項目を取得することになります。コードを示すと簡単になります (クラスは必要なものだけを表示するようにトリミングされています)。
モデル
class Report(models.Model):
name = models.CharField(max_length=255)
slug = AutoSlugField(_('slug'), populate_from='name')
wells = models.ManyToManyField(Well, null=True)
uuid = UUIDField(editable=False, blank=True, version=4, unique=True)
class Well(models.Model):
slug = AutoSlugField(_('slug'), populate_from='name')
name = models.CharField(max_length=255)
class Node(models.Model):
@property
def well(self):
raise NotImplementedError("The 'well' field must be implemented")
//irrelevant GFK omitted
page_content_type = models.ForeignKey(ContentType, null=True, blank=True, related_name='page')
page_object_id = models.PositiveIntegerField(blank=True, null=True)
page_content_object = generic.GenericForeignKey('page_content_type',
'page_object_id')
資力
class ReportResource(ModelResource):
wells = fields.ManyToManyField(WellResource, 'wells', full=True)
stock = fields.ForeignKey(TickerResource, 'stock', full=True)
class Meta:
queryset = Report.objects.all()
resource_name = 'ticker_reports'
class WellResource(ModelResource):
nodes = fields.ToManyField('wells.api.NodeResource', 'nodes', full=True)
type = fields.ForeignKey(WellTypeResource, 'type', full=True)
class Meta:
queryset = Well.objects.all()
resource_name = 'wells'
class NodeResource(ModelResource):
order = fields.IntegerField()
content_object = GenericForeignKeyField({
Content: UUIDOnlyContentResource
}, 'content_object', full=True)
class Meta:
queryset = Node.objects.all()
resource_name = 'nodes'
filtering = {
'ticker_report': ALL_WITH_RELATIONS
}
ティッカー レポートには多くのウェルがあり、これらのウェルはすべてのティッカー レポートで共有されます。異なる点は、ノードをウェルに関連付けることができることです。特定のティッカー レポートの場合、表示されるノードは、そのティッカー レポートに関連するノードのみです。
そのため、特定のティッカー レポートと一連のウェルについて、そのティッカー レポートの GenericForeignKey を共有するノードのみを表示する必要があります。
関係:
page_object_id
, page_content_object
,page_content_type
は Report への GenericForeignKey 関係です
現在、すべてのノードが表示されています (これはバグです)。
TastyPie で、すべてのオブジェクトではなく、関連するオブジェクトのみを表示するにはどうすればよいですか?
問題をより簡潔に示す短い python コンソールを次に示します。
>>> r = Report.objects.get(id=1)
>>> for well in r.wells.all():
... for node in well.nodes.all():
... print 'Node in Well {0} is {1}'.format(well, node)
...
Node in Well The Areas You Must Watch (the-areas-you-must-watch - Fancy List) is Apple Content #1:Apple (0)
Node in Well The Areas You Must Watch (the-areas-you-must-watch - Fancy List) is First Solar Content #1:first solar (0)
Node in Well Risks (risks - Headline and Lead) is Apple Content #2:Apple (0)
Node in Well Risks (risks - Headline and Lead) is First Solar Content #2:first solar (0)
>>>
SQL 実際の出力
SELECT node.id, node.uuid, node.order,node.content_type_id, node.object_id,
node.page_content_type_id, node.page_object_id, node.well_id FROM node
WHERE node.well_id = 1
ORDER BY node.order ASC
(読みやすいように修正しました)
予期される SQL 出力:
SELECT node.id, node.uuid, node.order,node.content_type_id, node.object_id,
node.page_content_type_id, node.page_object_id, node.well_id FROM node
WHERE node.well_id = 1 AND node.page_content_type_id = 99 /*Report Content TypeID */ AND node.page_content_object_id = 1 /*ReportID*/
ORDER BY node.order ASC
期待される出力:
Node in Well The Areas You Must Watch is Apple Content #1
Node in Well Risks is Apple Content #2:Apple (0)
Django および TastyPie との多対多の関係の子側を除外するにはどうすればよいですか (ただし、この問題は TastyPie がなくても明らかであり、構造的な問題だと思います)