Django高级查询

2024-10-01 00:24:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Django ORM来处理我的数据库查询。我有以下数据库表:

  • 资源
  • 资源池
  • 资源池
  • 预订

以及以下型号:

class Resource(models.Model):

    name = models.CharField(max_length=200)

class Reservation(models.Model):
    pass

class ResourcePool(models.Model):

    reservation = models.ForeignKey(Reservation, related_name="pools", db_column="reservation")
    resources = models.ManyToManyField(Resource, through="ResourcePoolElem")
    mode = models.IntegerField()

class ResourcePoolElem(models.Model):

    resPool = models.ForeignKey(ResourcePool)
    resource = models.ForeignKey(Resource)

目前,我需要查询一组预订中使用的资源。我使用以下查询:

^{pr2}$

我认为它与类似于此的sql查询匹配:

select *
from resource r join resource_pool rp join resource_pool_elem rpe join reservation reserv 
where r.id = rpe.resource and  
  rpe.pool = rp.id and
  reserv.id = rp.reservation and
  r.name in (resourcesNames[0], ..., resourcesNames[n-1])
  reserv.id in (reservations[0], ..., reservations[n-1])

现在,我想给这个查询添加一个限制。每个池可以有一个独占模式布尔标志。将有一个额外的输入列表,其中包含每个池的请求独占标志,我只想查询独占标志与请求的独占标志匹配的池的资源(如果exclusive=true)或独占标志为false的池的资源。我可以使用Python构建SQL查询,代码如下:

query = "select * 
    from resource r join resource_pool rp join resource_pool_elem rep
    join reservation reserv 
    where r.id = rpe.resource and  
    rpe.pool = rp.id and 
    reserv.id = rp.reservation and 
    reserv.id in (reservations[0], ..., reservations[n-1]) and ("
for i in resourcesNames[0:len(resourcesNames)]
    if i > 0:
        query += " or "
    query += "r.name = " + resourcesNames[i]
    if (exclusive[i])      
        query += " and p.mode == 0"
query += ")"    

有没有一种方法可以在Django查询中表达这个sql查询?在


Tags: andidmodels标志资源queryresourcerp
2条回答

也许你可以用Q objects来做这个。我对您的示例有一些问题,但是让我们用一个更简单的模型来看看。在

class Garage(models.Model):
    name     = models.CharField()

class Vehicle(models.Model):
    wheels   = models.IntegerField()
    gears    = models.IntegerField()
    garage   = models.ForeignKey(Garage)

假设你想把所有的“多轮”车辆都放在车库里(例如,所有的摩托车和汽车,但没有独轮车),但是对于汽车,你只想要那些带有无级变速器的车辆,这意味着它们只有一个档位。(这是怎么回事,没有线索,但请你忍受我。。。;)以下内容应能给您提供:

^{pr2}$

鉴于以下可用数据:

for v in Vehicle.objects.filter(garage=garage):
    print 'Wheels: {}, Gears: {}'.format(v.wheels, v.gears)

Wheels: 1, Gears: 1
Wheels: 2, Gears: 4
Wheels: 2, Gears: 5
Wheels: 4, Gears: 1
Wheels: 4, Gears: 5

运行查询将为我们提供:

for v in query:
    print 'Wheels: {}, Gears: {}'.format(v.wheels, v.gears)

Wheels: 2, Gears: 4
Wheels: 2, Gears: 5
Wheels: 4, Gears: 1

最后,为了使其适应您的情况,您可以使用以下代码:

query = models.Resource.objects.filter(Q(resPool__reservation__in=reservations))
query = query.filter(Q(name__in(resourcesNames))
query = query.filter(Q(resPool__exclusive=True) & Q(resPool__mode=0))

例如,可以使用django游标进行查询

参见文档: https://docs.djangoproject.com/en/dev/topics/db/sql/

from django.db import connection

def my_custom_sql(self):
    cursor = connection.cursor()

    cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])

    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()

    return row

相关问题 更多 >