Джанго оставил присоединиться - PullRequest
1 голос
/ 20 апреля 2009

У меня проблема с левым соединением .. У меня есть следующие модели

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, если он есть.

Прямо сейчас я делаю это в 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()

Ответы [ 3 ]

2 голосов
/ 20 апреля 2009

Вы можете использовать код, подобный следующему:

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

Что вернет список всех объектов CommandInfo, для которых s установлен в качестве внешнего ключа.

Более подробную информацию вы можете получить в документации Django, " После Отношений ".

0 голосов
/ 16 марта 2011
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

0 голосов
/ 21 апреля 2009

Иногда для Django ORM необходимо, чтобы имя левого поля соединения было явно задано с помощью select_related ().

Это просто не в моей голове, так что вам, вероятно, придется настроить его, но попробуйте что-то вроде:

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