在Django中,我如何高效地从一个一对一相关的表中获取相关数据?

huangapple go评论68阅读模式
英文:

How can I efficiently get related data from a 1 to 1 related table in Django?

问题

I have the following models.

class Event(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField()
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)

class Translation(models.Model):
    event = models.ForeignKey(Event, related_name="translation_event", on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)

I want to create a queryset on the Event table and then join that with the translated data.
In other words, I want a left outer join between the Event table and the Translation table.

If I have a queryset (called queryset) on the Event table, from what I understand from a number of examples I saw as well as the documentation, I should be able to do the following:

queryset = queryset.select_related("translation_event")
for event_obj in queryset:
    print(event_obj.title)
    print(event_obj.translation_event.title)

However, when Django gets to the for event_obj in queryset: line, it throws an exception:

django.core.exceptions.FieldError: Invalid field name(s) given in
select_related: 'translation_event'.

(It then lists some valid field names, fields in the Event table that have foreign key relationships to other tables.)

It almost seems like the select_related allows going from the Event table to other tables, but doesn't allow the other direction where the foreign key is in the second table - even though it should.

Any help would be appreciated.

英文:

I have the following models. (I include only part of the actual full definition since the rest isn't relevant to the question.)

class Event(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField()
    title = models.CharField(max_length=255)
    description = models.TextField(blank=True, null=True)

class Translation(models.Model):
    event = models.ForeignKey(Event, related_name="translation_event", on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=255)
    description = models.TextField(null=True, blank=True)

I want to create a queryset on the Event table and then join that with the translated data.
In other words, I want a left outer join between the Event table and the Translation table.

If I have a queryset (called queryset) on the Event table, from what I understand from a number of examples I saw as well as the documentation, I should be able to do the following:

queryset = queryset.select_related("translation_event")
for event_obj in queryset:
    print(event_obj.title)
    print(event_obj.translation_event.title)

However, when Django gets to the for event_obj in queryset: line, it throws an exception:

> django.core.exceptions.FieldError: Invalid field name(s) given in
> select_related: 'translation_event'.

(It then lists some valid field names, fields in the Event table that have foreign key relationships to other tables.)

It almost seems like the select_related allows going from the Event table to other tables, but doesn't allow the other direction where the foreign key is in the second table - even though it should.

Any help would be appreciated.

答案1

得分: 1

我希望我理解你的意思正确:你正在寻找反向查找,对吗?

TranslationEvent 很容易。

trnsl = Translation.objects.all().first()
print(trnsl.translation_event)

另一种方式叫做反向查找。一个 Translation 属于一个特定的 Event。但一个特定的 Event 可能有一组 Translation。我不知道这对你的用例是否有意义,但这是 ForeignKey 的逻辑。另一种选择是 OneToOneField更多)。短语“has a set of”已经让你了解到反向查找的Python语法。像这样做:

evnt = Event.objects.all().first()  # 抓取一个事件
for related_trnsl in evnt.translation_set.all():
    print(related_trnsl)

你可以在这里找到更多关于相关查找的信息。只需在网站上搜索“_set”,你会更快地找到它。

英文:

I hope I understand you correctly: You are looking for reverse lookups, right?

Going from Translation to Event is easy.

trnsl = Translation.objects.all().first()
print(trnsl.translation_event)

The other way round is called reverse lookup. One Translation belongs to one specific Event. But one specific Event can have a set of Translations. I don't know whether or not that makes sense for your usecase, but that is the logic of ForeignKey. An alternative would be OneToOneField (more). The phrasing "has a set of" already leads you to the python syntax of reverse lookups. Do it like this:

evnt = Event.objects.all().first()  # grab an event
for related_trnsl in evnt.translation_set.all():
    print(related_trnsl)

You`ll find more about related lookups here. Just search the site for "_set" and you'll find it quicker.

huangapple
  • 本文由 发表于 2023年5月7日 22:43:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定