[英]Django select_related chained foreign keys doesn't return non-direct related objects
我曾瀏覽過其他多個帖子,因此這篇帖子可能看起來很重復,但我找不到答案。 我是該平台的新手,所以如果這不是正確的方法,我深表歉意。
我使用Django 2.2
根據官方文檔,它說select_related()返回一個QuerySet,它將“遵循”外鍵關系,並在執行查詢時選擇其他相關對象數據: https : //docs.djangoproject.com/en/2.2 / REF /模型/查詢集/#選擇相關
這是官方示例:您可以按照與查詢外鍵類似的方式使用外鍵。 如果您具有以下型號:
from django.db import models
class City(models.Model):
# ...
pass
class Person(models.Model):
# ...
hometown = models.ForeignKey(
City,
on_delete=models.SET_NULL,
blank=True,
null=True,
)
class Book(models.Model):
# ...
author = models.ForeignKey(Person, on_delete=models.CASCADE)
然后調用Book.objects.select_related('author__hometown')。get(id = 4)將緩存相關的Person和相關的City:
# Hits the database with joins to the author and hometown tables.
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author # Doesn't hit the database.
c = p.hometown # Doesn't hit the database.
# Without select_related()...
b = Book.objects.get(id=4) # Hits the database.
p = b.author # Hits the database.
c = p.hometown # Hits the database.
這是我的代碼:
class Campaign(SlugifyNameMixin, TimeStampedModel, TimeFramedModel,
StatusModel):
STATUS = Choices(
('draft', _('Draft')),
('published', _('Published')),
('disabled', _('Disabled')),
)
banner = ThumbnailerImageField(verbose_name=_('Banner'),
help_text=_('Choose a representative banner image'),
upload_to='campaigns/banners/',
blank=True
)
tagline = models.CharField(max_length=150, verbose_name=_('Tagline'), help_text=_('A short campaign description'))
organization = models.ForeignKey(Organization,
on_delete=models.PROTECT,
related_name='campaigns',
verbose_name=_('Organization'),
help_text=_('Select the organization that this campaign belongs to.')
)
description = RichTextUploadingField(null=False, default='',
verbose_name=_('Description'),
help_text=_('A description of this campaign and what it aims to accomplish')
)
class Meta:
verbose_name = _("Campaign")
verbose_name_plural = _("Campaigns")
unique_together = ("organization", "slug")
permissions = (('change_campaign_status', 'Can change the status of campaigns'),)
def __str__(self):
return '%s' % (self.name)
def get_absolute_url(self):
return reverse('explore:campaign-detail', args=[self.organization.slug, self.slug])
class Action(SlugifyNameMixin, TimeStampedModel):
campaign = models.ForeignKey(Campaign,
on_delete=models.PROTECT,
related_name='actions',
verbose_name=_('campaign'),
help_text=_('Select the campaign that this action belongs to.')
)
class Meta:
verbose_name = _('Action')
verbose_name_plural = _('Actions')
permissions = (('change_action_status', 'Can change the status of actions'),)
def __str__(self):
return '%s' % (self.name)
class ActionMeta(TimeStampedModel, StatusModel):
STATUS = Choices(
('open', _('Open')),
('in-progress', _('In-Progress')),
('completed', _('Completed')),
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.PROTECT)
action = models.ForeignKey(Action, on_delete=models.CASCADE, related_name='metas', verbose_name=_('action'))
class Meta:
verbose_name = _('Action Meta')
verbose_name_plural = _('Action Metas')
unique_together = ('user', 'action')
def __str__(self):
return '%s-meta-%s' % (self.action.name, self.id)
我的問題是我無法檢索廣告系列對象
>>> camp11 = Campaign.objects.get(name='camp11')
>>> camp12 = Campaign.objects.get(name='camp12')
>>> action11u1 = Action.objects.get(name='action11u1')
>>> action12u1 = Action.objects.get(name='action12u1')
>>> am1 = ActionMeta.objects.create(user=u, action=action11u1)
>>> am2 = ActionMeta.objects.create(user=u, action=action12u1)
>>> a1 = ActionMeta.objects.select_related('action__campaign').get(pk=am1.pk)
>>> a1.campaign
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: 'ActionMeta' object has no attribute 'campaign'
>>> a1.action
<Action: action11u1>
這是數據庫查詢
>>> print(a1.query)
SELECT "core_actionmeta"."id", "core_actionmeta"."created", "core_actionmeta"."modified", "core_actionmeta"."status", "core_actionmeta"."status_changed", "core_actionmeta"."user_id", "core_actionmeta"."action_id", "core_action"."id", "core_action"."created", "core_action"."modified", "core_action"."name", "core_action"."slug", "core_action"."campaign_id", "core_campaign"."id", "core_campaign"."created", "core_campaign"."modified", "core_campaign"."start", "core_campaign"."end", "core_campaign"."status", "core_campaign"."status_changed", "core_campaign"."name", "core_campaign"."name_en", "core_campaign"."name_fa", "core_campaign"."slug", "core_campaign"."banner", "core_campaign"."tagline", "core_campaign"."tagline_en", "core_campaign"."tagline_fa", "core_campaign"."organization_id", "core_campaign"."description", "core_campaign"."description_en", "core_campaign"."description_fa" FROM "core_actionmeta" INNER JOIN "core_action" ON ("core_actionmeta"."action_id" = "core_action"."id") INNER JOIN "core_campaign" ON ("core_action"."campaign_id" = "core_campaign"."id") WHERE "core_actionmeta"."id" = 3
您仍然需要action
。 嘗試:
>>> a1.action.campaign
旁注:我可能會更改ActionMeta
的名稱,只是因為Meta
具有如此特定的含義,並且已經有一個Action.Meta
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.