Python 如何使用django ORM进行多重连接和聚合?

Python 如何使用django ORM进行多重连接和聚合?,python,database,django,Python,Database,Django,Django/Python/ormnoob在这里!我很难理解如何参与ORM工作 以下是我的模型: class Courts(models.Model): id = models.AutoField(primary_key=True) location_name = models.CharField(max_length=100) number = models.IntegerField() def __unicode__(self): return

Django/Python/ormnoob在这里!我很难理解如何参与ORM工作

以下是我的模型:

class Courts(models.Model):
    id = models.AutoField(primary_key=True)
    location_name = models.CharField(max_length=100)
    number = models.IntegerField()
    def __unicode__(self):
        return "%s %s %s" % (self.id, self.location_name, self.number)

class Matches(models.Model):
    id = models.AutoField(primary_key=True)
    date = models.DateTimeField()
    court = models.ForeignKey(Courts)
    def __unicode__(self):
        return "%s %s" % (self.id, self.date)

class Participants(models.Model):
    id = models.AutoField(primary_key=True)
    match = models.ForeignKey(Matches)
    userid = models.ForeignKey(User)
    games_won = models.IntegerField()
    def __unicode__(self):
        return "%s %s %s" % (self.id, self.games_won, self.userid)
第一步是将所有“参与者”输入如下输出:

[match_id] [date]       [userid]  [games_won]  [court_location_name]  [court_number]
1          01-01-2011   mike      6            Queen                  5
1          01-01-2011   chris     4            Queen                  5
2          01-02-2011   bob       3            Queen                  6
2          01-02-2011   joe       4            Queen                  6
3          01-03-2011   jessie    5            Queen                  2
3          01-03-2011   john      5            Queen                  2
我将编写什么ORM脚本来获取此信息?我很难理解简单连接是如何与ORM一起工作的,更不用说组合3个表了

接下来,我要聚合数据,使其最终看起来像这样:

[match_id] [date]       [player1] [player2]  [p1wins] [p2wins] [game_winner] [court_location_name]  [court_number]
1          01-01-2011   mike      chris      6        4        mike          Queen                  5
2          01-02-2011   bob       joe        3        4        joe           Queen                  6
3          01-03-2011   jessie    john       5        5        draw          Queen                  2  
def index(request):
    matches_list = Participants.objects.all()
    return render_to_response('squash/base_matches.html', {'matches_list': matches_list}, context_instance = 
RequestContext(request))
    return HttpResponse(output)
{% for matches in matches_list %}
    <tr>
        <td>{{ matches.id }}</td> 
        <td>{{ matches.date|date:"d-m-Y" }}</td>
        <td>{{ matches.date|date:"G:i" }}</td>
    </tr>
    {% endfor %}
这是否会改变我将要编写的ORM脚本(在视图中)?这是我需要合并到视图或模板中的内容吗

更新:

所以,我想我可以用。所以我尝试了Participants.objects.select_related()并得到了这个SQL语句

SELECT "squash_participants"."id", "squash_participants"."match_id", "squash_participants"."userid_id", "squash_participants"."games_won", "squash_matches"."id", "squash_matches"."date", "squash_matches"."court_id", "squash_courts"."id", "squash_courts"."location_name", "squash_courts"."number", "auth_user"."id", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."password", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."is_superuser", "auth_user"."last_login", "auth_user"."date_joined" FROM "squash_participants" INNER JOIN "squash_matches" ON ("squash_participants"."match_id" = "squash_matches"."id") INNER JOIN "squash_courts" ON ("squash_matches"."court_id" = "squash_courts"."id") INNER JOIN "auth_user" ON ("squash_participants"."userid_id" = "auth_user"."id"
这看起来更像是我想要达到的目标。现在我不知道如何将数据从中提取到模板中

更新2:

我的观点是这样的:

[match_id] [date]       [player1] [player2]  [p1wins] [p2wins] [game_winner] [court_location_name]  [court_number]
1          01-01-2011   mike      chris      6        4        mike          Queen                  5
2          01-02-2011   bob       joe        3        4        joe           Queen                  6
3          01-03-2011   jessie    john       5        5        draw          Queen                  2  
def index(request):
    matches_list = Participants.objects.all()
    return render_to_response('squash/base_matches.html', {'matches_list': matches_list}, context_instance = 
RequestContext(request))
    return HttpResponse(output)
{% for matches in matches_list %}
    <tr>
        <td>{{ matches.id }}</td> 
        <td>{{ matches.date|date:"d-m-Y" }}</td>
        <td>{{ matches.date|date:"G:i" }}</td>
    </tr>
    {% endfor %}
我的模板如下所示:

[match_id] [date]       [player1] [player2]  [p1wins] [p2wins] [game_winner] [court_location_name]  [court_number]
1          01-01-2011   mike      chris      6        4        mike          Queen                  5
2          01-02-2011   bob       joe        3        4        joe           Queen                  6
3          01-03-2011   jessie    john       5        5        draw          Queen                  2  
def index(request):
    matches_list = Participants.objects.all()
    return render_to_response('squash/base_matches.html', {'matches_list': matches_list}, context_instance = 
RequestContext(request))
    return HttpResponse(output)
{% for matches in matches_list %}
    <tr>
        <td>{{ matches.id }}</td> 
        <td>{{ matches.date|date:"d-m-Y" }}</td>
        <td>{{ matches.date|date:"G:i" }}</td>
    </tr>
    {% endfor %}
{%用于匹配项列表%}
{{matches.id}
{matches.date}日期:“d-m-Y”}
{{matches.date}日期:“G:i”}
{%endfor%}
它正确地呈现所有的
参与者.id
s,但不会带来比赛id、日期或场地等

这里有几个“东西”:

  • 定义“id”主字段是不必要的,因此容易混淆,Django会自动生成它们
  • 使用单数形式命名模型是一种很好的做法(即使用Match而不是Matches等),这样可以让Django提供适当的名称。这也是合乎逻辑的,因为Match类的对象表示单个匹配,而不是多个匹配——对于多个匹配,您使用模型管理器:Match.objects
  • 您的“参与者”模型实际上是中间的manytomy表,您可以在“匹配”模型中显式地声明它,如
  • 现在,关于连接问题,我支持S.Lott的方法,我曾经在StackOverflow的某个地方读到过它——你不应该考虑Django中的连接,因为Django ORM(“O”代表“对象”——将SQL映射到对象不是一件容易的事)不是这样工作的。您应该专注于完成您的工作,并且仅在合理的情况下使用联接,如性能问题

    最后,回答你的问题:

    Participants.objects.all()
    
    :-)

    您可以通过使用获得更好的性能,如果需要,还可以使用应用排序

    至于聚合,其他人可能会提供一个一行解决方案,我目前还没有看到,但现在您可以将其添加到“匹配”模型中:

    然后,您可以用最简单的方法获取匹配项:

    Matches.objects.all()
    
    然后,返回集的每个元素都将具有“players”属性

    更新:

    要将数据传递到模板,只需将其添加到模板呈现上下文:


    使用快捷功能可以简化此操作。

    Tomasz,感谢您的回复。也要欣赏这些指南和提示。有趣的是,当我开始在ORMShell中进行测试时,我开始意识到
    参与者.objects.all
    才是正确的选择。我遇到的问题是调用哪些变量以在模板层中获取数据。我的视图是这样设置的:
    matches\u list=particients.objects.all()
    我的模板是这样设置的
    {%formatches\u list%}{{matches.id}}
    。例如,我不知道如何提取'date'列。您应该能够简单地使用{{matches.date}},或者通过使用日期过滤器使格式更好:这就是我所拥有的
    {{matches.date | date:'d-m-Y}{matches.date | date:'G:I}
    ,但这不起作用。我想这就是为什么我在使用objects.all()时遇到这么多问题的原因。我的观点有问题吗?这里:
    def index(request):matches_list=Participants.objects.all()返回render_to_response('squash/base_matches.html',{'matches_list':matches_list},context_instance=RequestContext(request))返回HttpResponse(output)
    您能用这些片段更新您的答案吗(但要长一点,以掌握整个上下文)?这里的评论有点不可读。你对此感到抱歉。现在更新。再次感谢