[英]retrieving the 'many' end of a Generic Foreign Key relationship in Django
在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
}
Ticker報告有很多Wells,這些Wells在所有Ticker報告中共享。 不同的是你可以將節點綁定到Wells; 對於給定的股票報告,應顯示的唯一節點是與該股票報告相關的節點。
因此,對於給定的股票報告和一組井,只應顯示與該Ticker報告共享該GenericForeignKey的節點。
關系:
page_object_id
, page_content_object
, page_content_type
是與報告的page_object_id
關系
目前,顯示所有節點(這是一個錯誤)。
在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)
>>>
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
(修改后更容易閱讀)
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這個問題很明顯,讓我相信這是一個結構性問題)
執行查詢時
well.nodes.all()
這將通過您在模型中描述的關系獲取與well
相關的所有節點。
聽起來好像要通過page_content_object
通用外鍵關系將返回的節點限制為引用Report
對象r
的節點。 是對的嗎? 如果是,則需要顯式過濾節點,如下所示:
r = Report.objects.get(id=1)
for well in r.wells.all():
for node in well.nodes.filter(page_object_id = r.id,
page_content_type = ContentType.objects.get_for_model(r)):
# ...
更新:我對TastyPie一無所知,我不得不說我真的不明白你想要做什么,但是在Django中,如果井和節點之間存在關系,那么你需要將它添加到你的模特。 例如,如果每個Node
屬於一個Well
,那么自然要做的就是向Node
模型添加一個字段:
class Node(models.Model):
# ...
well = models.ForeignKey('Well')
然后,如果要查找屬於特定Report
對象r
井的所有節點,所述節點也通過通用外鍵關系引用r
,則發出查詢:
Node.objects.filter(well__report = r,
page_object_id = r.id,
page_content_type = ContentType.objects.get_for_model(r))
如果你必須做很多事情,那么自然要做的就是在Report
模型上添加一個方法。
Ticker報告有很多Wells,這些Wells在所有Ticker報告中共享。 不同的是你可以將節點綁定到Wells; 對於給定的股票報告,應顯示的唯一節點是與該股票報告相關的節點。
在Django中,當我請求具有多對多關系的資源時,我最終得到關系的子部分中的所有項目,即使那些與父項沒有直接關系的項目也是如此。 如果我向你展示代碼(修剪的類只顯示必要的內容)會更容易:
如果我理解正確,節點可以與報告或井相關 (因為您提到與該Ticke報告相關 )。 您正在尋找與報告相關的節點 ,而不是與報告的井相關的節點 。 (因為你正在尋找與父母直接相關的節點(報告?))
如果我是正確的,那很簡單:
https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#reverse-generic-relations
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)
nodes = generic.GenericRelation(Node)
# usage
r = Report.objects.get(id=1)
nodes = r.nodes.all()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.