Reputation: 7841
I have a bit of a left join issue.. I have the following models
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
I need to grab all the server instances and left join the CommandInfo to it if there is one.
Right now I'm doing it in raw 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()
Upvotes: 1
Views: 4143
Reputation: 31
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, [])
Please note that you need to get the servers list due you can servers without CommandInfo
Upvotes: 0
Reputation: 43912
Sometimes the Django ORM needs the left join field name to be explicitly name with select_related().
This is just off the top of my head so you'll probably need to tweak it, but try something like:
s = Server.objects.select_related('commandinfo_set')
Upvotes: 0
Reputation: 410722
You can use code like the following:
s = Server.objects.get(id=1)
cmdinfo = s.commandinfo_set.all()
Which would return a list of all CommandInfo objects that have s
set as the foreign key.
You can get more info at the Django docs, "Following Relationships Backward".
Upvotes: 2