我有两个这样的模型:
class ObjectLock(models.Model):
partner = models.ForeignKey(Partner)
object_id = models.CharField(max_length=100)
class Meta:
unique_together = (('partner', 'object_id'),)
class ObjectImportQueue(models.Model):
partner = models.ForeignKey(Partner)
object_id = models.CharField(max_length=100)
... # other fields
created = models.DateTimeField(auto_now_add = True)
modified = models.DateTimeField(auto_now = True, db_index=True)
class Meta:
ordering = ('modified', 'created')
上面提到的第三种模式(合作伙伴)没有什么值得注意的。
我想得到类似的东西:
SELECT * FROM ObjectImportQueue q LEFT OUTER JOIN ObjectLock l ON
q.partner_id=l.partner_id AND q.object_id=l.object_id WHERE l.object_id
IS NULL and l.partner_id IS NULL;
我遇到了this page,它告诉我们如何进行自定义连接,并且我尝试传入列名称的元组来代替要加入的列名称,但这不起作用。合作伙伴表不应该包含在生成的sql查询中,但我会接受包含它的答案,只要它有效地执行我正在尝试对一个查询执行的操作。
答案 0 :(得分:1)
如果你正在使用Django 1.2+并且知道你想要的SQL,你总是可以回到Raw Query.
答案 1 :(得分:1)
我也遇到了类似的问题。但最后,我发现我提出了一个错误的问题需要解决。
在Django ORM中,SQL连接的条件基于models.Model
字段定义的内容。
有多对一关系(ForeignKey
),多对多关系(ManyToManyField
),一对一关系(OneToOneField
)。
在您的情况下。ObjectLock
模型和ObjectImportQueue
模型具有相同的字段部分,partner
字段和object_id
字段.Yon应使用一对一关系。
您可以像这样更改模型:
class ObjectImportQueue(models.Model):
partner = models.ForeignKey(Partner)
object_id = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add = True)
modified = models.DateTimeField(auto_now = True, db_index=True)
def __unicode__(self):
return u"%s:%s" % (self.partner, self.object_id)
class Meta:
ordering = ('modified', 'created')
class ObjectLock(models.Model):
lock = models.OneToOneField(ObjectImportQueue, null=True)
class Meta:
unique_together = (('lock',),)
模型的顺序是导入的,OneToOneField
参数模型必须首先出现。
>>> p1 = Partner.objects.get(pk=1)
>>> p2 = Partner.objects.get(pk=2)
>>> Q1 = ObjectImportQueue.objects.create(partner=p1,object_id='id_Q1')
>>> Q2 = ObjectImportQueue.objects.create(partner=p2,object_id='id_Q2')
>>> ObjectImportQueue.objects.filter(lock__isnull=True)
[<ObjectImportQueue: Partner object:id_Q1>, <ObjectImportQueue: Partner object:id_Q2>]
>>> L1 = ObjectLock.objects.create(lock=Q1)
>>> ObjectImportQueue.objects.filter(lock__isnull=True)
[<ObjectImportQueue: Partner object:id_Q2>]
ObjectLock.objects.create
锁定一个对象
ObjectImportQueue.objects.filter(lock__isnull=True)
选择对象不会被锁定。
如果使用适当的关系,生成ORM查询将很容易。在Django中,在构建Model时定义关系比使用Query语句来关联表之间的关系更好。
答案 2 :(得分:0)
我刚刚找到了解决这个问题的方法。
您必须创建一个为您执行连接的视图
CREATE VIEW ImporQueueLock AS (
SELECT q.id, l.id
FROM ObjectImportQueue q
LEFT OUTER JOIN ObjectLock l
ON q.partner_id=l.partner_id AND q.object_id=l.object_id
)
然后为该视图制作一个django模型
class ImportQueueLock(models.Model):
queue = models.ForeignKey(ObjectImportQueue, db_column='q')
lock = models.ForeignKey(ObjectLock, db_column='l')
然后通过ImportQueueLock在您的Django模型上创建一个ManyToMany,从ObjectLock到ObjectImportQueue
class ObjectLock(models.Model):
partner = models.ForeignKey(Partner)
object_id = models.CharField(max_length=100)
queue = models.ManyToManyField(ObjectImportQueue, through = ImportQueueLock)
你可以做到
ObjectLock.objects.filter(importqueuelock__objectimportqueue__ .....)