Django 使用 ORM 和条件 Where 子句连接表
Posted
技术标签:
【中文标题】Django 使用 ORM 和条件 Where 子句连接表【英文标题】:Django join tables with ORM and conditional Where clause 【发布时间】:2019-03-15 16:07:04 【问题描述】:我有 4 张桌子要加入;人员、机器和地点。如果请求正文包含过滤数据,我想加入这些表并将 where 子句添加到 ORM 查询的末尾。这是我的模型和原始查询(我想在 django ORM 中编写此查询)和 where 子句的 if 条件示例;
模型;
class Sales(models.Model):
MachineId = models.ForeignKey(Machines,on_delete=models.CASCADE,db_column='MachineId',related_name='%(class)s_Machine')
PersonnelId = models.ForeignKey(Personnels,on_delete=models.CASCADE,db_column='PersonnelId',related_name='%(class)s_Personnel')
LocationId = models.ForeignKey(Locations,on_delete=models.CASCADE,db_column='LocationId',related_name='%(class)s_Location')
class Meta:
db_table = "Sales"
class Machines(models.Model):
Name = models.CharField(max_length=200)
Fee = models.DecimalField(max_digits=10,decimal_places=3)
class Meta:
db_table = "Machines"
class Personnels(models.Model):
name = models.CharField(max_length=200)
surname = models.CharField(max_length=200)
class Meta:
db_table = "Personnels"
class Locations(models.Model):
Latitude = models.FloatField()
Longitude = models.FloatField()
LocationName = models.CharField(max_length=1000)
class Meta:
db_table = "Locations"
如您所见,我有 4 个模型。 “销售”表具有其他人的外键。我想使用这些外键获取表中的所有信息。(使用内连接)
query = '''select * from "Sales" as "SL" INNER JOIN "Personnels" as "PL" ON ("SL"."PersonnelId" = "PL"."user_id") INNER JOIN "Machines" as "MC" ON ("SL"."MachineId" = "MC"."id") INNER JOIN "Locations" as "LC" ON ("SL"."LocationId" = "LC"."id") '''
if request.method=='POST':
if request.data['personnel_name'] and request.data['personnel_name'] is not None:
personnel_name = request.data['personnel_name']
condition = '''WHERE "PL"."name" = '0' '''.format(personnel_name)
query = query+condition
正如所见,有很多引号(如果我不写,postgresql 会麻烦)并且代码不干净。
我的问题是,如何使用 django ORM 编写此查询?如您所见,我想动态添加 where 条件。我怎样才能做到这一点?
【问题讨论】:
您应该在此处添加您的型号代码。一般模式是这样的。Sales.objects.filter(personell__name=name)
。 docs.djangoproject.com/en/2.1/topics/db/queries/… 仅从这段代码中,我并不清楚 Location、Personell、Machine 和 Sale 表之间的关系,以及输出中需要哪些字段。
你说得对,我添加了我的模型。
请尽可能用最简单的语言描述您想要完成的查询(例如“我希望所有位置都至少有一台机器”)等。这样会更容易提供帮助。
我写了一个简短的描述。
【参考方案1】:
我将使用传统的命名方式,只有类名大写,模型名单数。
class Sale(models.Model):
machine = models.ForeignKey(Machine, on_delete=models.CASCADE)
person = models.ForeignKey(Person, on_delete=models.CASCADE)
location = models.ForeignKey(Location, on_delete=models.CASCADE)
db_column
和 db_table
如果您必须使用现有数据库连接 django 应用程序,则很有用。如果没有,django 将默认创建合理的表名。表名可以与模型字段名不同。
要创建join where
,请使用queryset filter。
Sale.objects.filter(person__name='Jane Janes')
您可能不需要更多的连接,因为 django 会在需要时执行额外的查询,但可以使用 select_related 来实现,并且可以为您提供更好的性能,因为它减少了所需的 sql 查询总数。
Sale.objects.filter(person__name='Jane Janes').select_related('machine', 'person', 'location')
在评估查询集时检查将执行的实际 SQL 会很有用。您可以通过访问QuerySet.query
属性来做到这一点。
queryset = Sale.objects.select_related('machine').filter(
person__name='Jim', location__name='London')
print(queryset.query)
【讨论】:
以上是关于Django 使用 ORM 和条件 Where 子句连接表的主要内容,如果未能解决你的问题,请参考以下文章
如何在 pynamodb ORM 中使用多个 where 条件
laravel orm where 条件中 mysql函数 怎么用
laravel orm where 条件中 mysql函数 怎么用