繁体   English   中英

Django ORM 左连接 SQL

[英]Django ORM LEFT JOIN SQL

下午好)请告诉我,外键中的django模型中有一个外键,在创建连接时,它会在_id数据库中创建一个单元格,随后它会执行JOIN查询,请告诉我如何指定你自己的单元格加入哪个,我无法在已创建的数据库中创建表


I need a banal simple LEFT JOIN without connection with _id.
Or specify another cell in the database for JOIN instead of _id, for example
CastleModels.id = ClanModels.hasCastle


class ClanInfoModels(models.Model):
    clan_id = models.IntegerField()
    name = models.CharField(max_length=80)

    class Meta:
        db_table = 'clan_subpledges'
        managed = False


class ClanModels(models.Model):
    clan_id = models.IntegerField()
    hasCastle = models.IntegerField(primary_key=True)

    class Meta:
        db_table = 'clan_data'
        managed = False


class CastleModels(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=11)

    class Meta:
        db_table = 'castle'
        managed = False
        ordering = ['id']
need sql query = 

SELECT castle.name,castle.id,clan_subpledges。 name as 'name_clan' FROM castle LEFT JOIN clan_data ON clan_data.hasCastle = castle.id LEFT JOIN clan_subpledges ON clan_subpledges.clan_id = clan_data.clan_id

只需命名您的领域。

class ClanModels(models.Model):
    clan_id = models.IntegerField()
    hasCastle = models.ForeignField('CastleModels', db_column='hasCastle', on_delete=models.Cascade)

您可以使用子查询来解决您的问题,但您不应该这样做。 我认为您的代码的问题是模型没有正确定义。 它应该是这样的:

class ClanInfo(models.Model):
    clan = models.ForeignKey('Clan')
    name = models.CharField(max_length=80)

    class Meta:
        db_table = 'clan_subpledges'
        managed = False


class Clan(models.Model):
    id = models.IntegerField(primary_key=True)
    hasCastle = models.ForeignKey('Castle')

    class Meta:
        db_table = 'clan_data'
        managed = False


class Castle(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=11)

    class Meta:
        db_table = 'castle'
        managed = False
        ordering = ['id']

然后你可以像这样简单地查询:

 Castle.objects.values('name', 'id', 'clan__claninfo__name')

要了解反向查询的工作原理,请阅读文档 仅供参考:我从每个 model class 名称中删除了Models ,因为您不需要将模型放入 class 名称中,将其标识为 model。

除此之外,如果您坚持保留现有代码,那么以下代码可能会使用子查询

from django.db.models import OuterRef, Subquery


outer_query = ClanInfo.objects.filter(clan_id=OuterRef('id'))
CastleModels.objects.annotate(clan_subpledges=Subquery(outer_query.values('name')[:1]).values('id', 'name', 'clan_subpledges')

利用 Django model 定义中的db_column选项。

db_column:用于此字段的数据库列的名称。

你的 SQL 可以写成

from django.db.models import F
from .models import CastleModels

queryset = CastleModels.objects.values('name', 'id', name_clan=F('clanmodels__claninfomodels__name'))

我无法完全推断出您的 model 设计,但如果

  1. 一座城堡可以容纳零个或多个氏族,并且
  2. clan_id实际上是一个氏族的主键。

那么模型可以定义为:

class CastleModels(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=11)

    class Meta:
        db_table = 'castle'
        managed = False
        ordering = ['id']

class ClanModels(models.Model):
    clan_id = models.IntegerField(primary_key=True) 
    hasCastle = models.ForeignKey(CastleModels, on_delete=models.DO_NOTHING, db_column='hasCastle')

    class Meta:
        db_table = 'clan_data'
        managed = False

class ClanInfoModels(models.Model):
    clan_id = models.OneToOneField(ClanModels, on_delete=models.DO_NOTHING, db_column='clan_id')
    name = models.CharField(max_length=80)

    class Meta:
        db_table = 'clan_subpledges'
        managed = False

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM