Question

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()
Was it helpful?

Solution

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".

OTHER TIPS

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')
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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top