2009-04-20 61 views
1

我都有点左派的加盟问题..我有以下型号Django的左加入

class CommandInfo(models.Model): 
    server = models.ForeignKey(Server) 
    count = models.IntegerField(default=1) 
    ts = models.DateTimeField(auto_now=True) 

class Server(models.Model): 
    name = models.CharField(max_length=100) 
    group = models.ForeignKey(ApplicationGroup, blank=True, default=0) 
    host = models.CharField(max_length=100) 
    ip = models.IPAddressField(db_index=True) 
    about = models.TextField() 
    firstTS = models.DateTimeField(auto_now_add=True) 
    lastTS = models.DateTimeField(auto_now=True) 
    processed = models.SmallIntegerField(max_length=1, default=0) 

    def __unicode__(self): 
     return self.host 

我需要抓住所有的服务器实例和左加入CommandInfo的它是否有一个。

现在我正在做它原始的SQL

from django.db import connection 
cursor = connection.cursor() 
cursor.execute("SELECT host,ts,count as host FROM servers_server LEFT JOIN cmds_commandinfo ON server_id=servers_server.id") 
servers = cursor.fetchall() 

回答

2

您可以使用如下代码:

s = Server.objects.get(id=1) 
cmdinfo = s.commandinfo_set.all() 

这将返回有s集所有CommandInfo的对象的列表外键。

您可以在Django文档“Following Relationships Backward”中获得更多信息。

0

有时Django ORM需要左连接字段名称与select_related()显式名称。

这只是我的头的顶部,这样你可能需要调整它,但你可以试试:

s = Server.objects.select_related('commandinfo_set') 
+1

`.select_related`不适用于后向关系,所以这不起作用。它只适用于调用方法的模型中的`ForeignKey`和`OneToOneField`字段。 – 2010-10-18 08:24:23

0
commands_by_server_id = defaultdict(list) 
for c in CommandInfo.objects.select_related('server'): 
    commands_by_server_id[c.server.id].append(c) 

servers = Server.objects.all() 
for s in servers: 
    s.commands = commands_by_server_id.get(s.id, []) 

请注意,你需要得到你应有的服务器列表可以没有CommandInfo的服务器