如何在Django查询中编写连接条件

1 投票
2 回答
720 浏览
提问于 2025-04-18 00:07

我想知道在Django查询中,如何写出一个连接条件,来实现以下的SQL查询:

SELECT
    s.name,
    l.name,
    a.name,
    a.asset_code,
    c.name,
    ad.name,
    a.model_no,
    a.serial_no
FROM
    asset_mgmt_asset_assignment_employee ae,
    asset_mgmt_asset a,
    asset_mgmt_department ad,
    asset_mgmt_employee e,
    asset_mgmt_sublocation s,
    asset_mgmt_location l,
    asset_mgmt_asset_category c
WHERE
    ae.asset_id = a.id AND
    ae.department_id = ad.id AND
    ae.employee_id = e.id AND
    ad.location_id = l.id AND
    l.Sublocation_id = s.id AND
    c.id = a.asset_category_id AND
    s.id = 2;

我们该如何在Django查询中把这些表都混合在一起呢?

2 个回答

0

在Django中,你不需要自己写连接查询。Django有一个引擎,它会自动判断什么时候需要进行连接操作,并为你处理这些事情。

你的任务是正确地创建模型,以便它们之间的关系能够正确表示;然后就可以让ORM(对象关系映射)来处理查询和表的创建。

根据你上面的查询,这里有一种可能的方式将其映射到ORM,并写出相应的API调用,以获取与某个资产相关的所有对象。当然,这里并没有涵盖所有内容,但应该能给你一个大致的思路:

class Department(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return unicode(self.name)

class Location(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey('self', blank=True, null=True)

    def __unicode__(self):
        return unicode(self.name)

class AssetCategory(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):
        return unicode(self.name)

class Employee(models.Model):
    name = models.CharField(max_length=100)
    department = models.ForeignKey(Department)

    def __unicode__(self):
        return unicode(self.name)

class Asset(models.Model):
    name = models.CharField(max_length=100)
    model_number = models.CharField(max_length=100)
    serial_number = models.CharField(max_length=100)
    employee = models.ForeignKey(Employee)
    location = models.ForeignKey(Location)
    category = models.ForeignKey(AssetCategory)

那么你的查询就是:

assets = Asset.objects.filter(location=Location.objects.get(id=2))
for asset in assets:
    print('{0.id}, {0.name}, {0.model_number}, {0.serial_number}'.format(asset))
    print('{0.employee}, {0.employee.department}, {0.location}'.format(asset)) 
0

这个查询在Django中并不能直接转换。Django的查询会生成对象,而不是元组。你需要从对象及其关系的角度来思考,而不是元组和关系。

当然,这个前提是ORM(对象关系映射)适合你的使用场景。如果你发现自己写了很多这样的查询,可能ORM就不太合适了。ORM最适合的情况是你想把所有的业务逻辑放在高层的应用代码中,把数据库当作对象的存储层。对于像这样的任意查询,ORM就不太好用了。就我个人而言,我并不太喜欢ORM。我更倾向于把大部分关系逻辑放在视图中,偶尔从应用代码中查询这些视图(用非常简单的查询)。不过这就涉及到个人观点了。ORM确实有它的价值,如果你想遵循类似MVC的框架,它会很有用,而更关系型的解决方案通常会产生更少的层次化代码。

撰写回答