如何使用django ORM在外键字段上连接两个表?

Lee*_*idt 22 python database django postgresql orm

我们假设我有以下模型:

class Position(models.Model):
    name = models.CharField()

class PositionStats(models.Model):
    position = models.ForeignKey(Position)
    averageYards = models.CharField()
    averageCatches = models.CharField()

class PlayerStats(models.Model):
    player = models.ForeignKey(Player)
    averageYards = models.CharField()
    averageCatches = models.CharField()

class Player(models.Model):
    name = models.CharField()
    position = models.ForeignKey(Position)
Run Code Online (Sandbox Code Playgroud)

我想使用django的ORM执行等效的SQL查询:

SELECT *

FROM PlayerStats

JOIN Player ON player

JOIN PositionStats ON PositionStats.position = Player.position
Run Code Online (Sandbox Code Playgroud)

我怎么能用django的ORM做到这一点?查询是不完全正确的,但这个想法是我想要一个单一的查询,使用Django的ORM,这给了我PlayerStats加入了与PositionStats基于玩家的位置.

Emd*_*won 11

select_related()prefetch_related()为您的解决方案。它们的工作方式几乎相同,但有一些不同。

select_related()通过创建 SQL 连接并在 SELECT 语句中包含相关对象的字段来工作。为此,select_related在同一数据库查询中获取相关对象。但它只适用于一对一或一对多的关系。示例如下-

entry = Entry.objects.select_related('blog').get(id=5)
or
entries = Entry.objects.filter(foo='bar').select_related('blog')
Run Code Online (Sandbox Code Playgroud)

prefetch_related(),另一方面,对每个关系进行单独的查找,并在 Python 中进行“连接”。这允许它预取多对多和多对一对象,这是使用select_related. 所以prefetch_related对于每个关系只会执行一个查询。示例如下-

Pizza.objects.all().prefetch_related('toppings')
Run Code Online (Sandbox Code Playgroud)


dok*_*ebi 10

这不是一个查询,但它非常有效.这会对所涉及的每个表执行一次查询,并在Python中将它们连接起来.更多信息请prefetch_related访问:https://docs.djangoproject.com/en/dev/ref/models/querysets/#prefetch-related

Player.objects.filter(name="Bob").prefetch_related(
        'position__positionstats_set', 'playerstats_set')
Run Code Online (Sandbox Code Playgroud)


小智 7

我已经和django一起工作了一段时间,我已经有一段非常艰难的时间搞清楚桌子加入了,但我想我终于理解了,我想把它传递给其他人,这样他们就可以避免我的挫败感了用它.

考虑以下model.py:

class EventsMeetinglocation(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=100)
    address = models.CharField(max_length=200)

    class Meta:
        managed = True
        db_table = 'events_meetinglocation'


class EventsBoardmeeting(models.Model):
    id = models.IntegerField(primary_key=True)
    date = models.DateTimeField()
    agenda_id = models.IntegerField(blank=True, null=True)
    location_id = models.ForeignKey(EventsMeetinglocation)
    minutes_id = models.IntegerField(blank=True, null=True)

    class Meta:
       managed = True
       db_table = 'events_boardmeeting'
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以看到EventsBoardmeeting中的location_id是EventsMeetinglocation中id的外键.这意味着我们应该能够通过EventsBoardmeeting查询EventsMeetinglocation中的信息.

现在考虑以下views.py:

def meetings(request):
    meetingData = EventsBoardmeeting.objects.all()
    return render(request, 'board/meetings.html', {'data': meetingData })
Run Code Online (Sandbox Code Playgroud)

如前所述,在其他帖子中,django会自动处理连接.当我们在EventsBoardmeeting中查询所有内容时,我们也可以通过外键获取任何相关信息,但是我们在html中访问它的方式有点不同.我们必须通过用作外键的变量来访问与该连接相关联的信息.例如:

{% for x in data %}
   {{ x.location_id.name }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

上面引用了表中所有的名称,这些名称是外键连接的结果.x本质上是EventsBoardmeeting表,因此当我们访问x.location_id时,我们正在访问外键,这使我们可以访问EventsMeetinglocation中的信息.

  • 我无法向您描述这篇文章有多么有用。我已经在互联网上搜索了近一周,试图弄清楚如何从 html 中加入的数据集中调用变量。如果我打印它,我可以在查询集中看到我想要的数据,但我一生都无法弄清楚如何让它显示在页面中。谢谢你! (2认同)