带有ORM和条件Where子句的Django联接表

时间:2018-10-10 17:05:08

标签: python django postgresql django-views django-orm

我有4个表要加入;人员,机器和位置。如果请求正文包括过滤数据,我想加入这些表并在ORM查询的末尾添加where子句。这是我的模型和原始查询(我想在django ORM中编写此查询),并为where子句确定条件条件;

模型;

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编写此查询?如您所见,我想动态添加条件。我该如何实现?

1 个答案:

答案 0 :(得分:0)

我将使用传统的命名方式,只对类名称进行大写字母化,而对模型名称使用单数形式。

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)
如果必须使用现有数据库连接django应用,则

db_columndb_table很有用。如果没有,django将默认创建明智的表名。表名称可以与模型字段名称不同。

要创建join where,请使用queryset filter

Sale.objects.filter(person__name='Jane Janes')

您可能不需要更多的联接,因为django会在需要时执行其他查询,但是可以使用select_related来实现,并且由于它减少了所需的sql查询总数,因此可以提供更好的性能。 / p>

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)