django不使用外键怎么实现INNER JOIN

现在有两个数据表:

class Goods(models.Model):
    """商品表"""
    name = models.CharField('名称', max_length=50)
    num = models.IntegerField('数量', default=0)
    shop_id = models.IntegerField('店铺ID')

class Shop(models.Model):
    """店铺表"""
    name = models.CharField('店铺名称', max_length=50)
    reputation = models.SmallInteger('店铺信誉', default=1, help_text='范围:1~5')

查询商品的时候希望通过商品数量和店铺信誉进行联合排序,SQL是这样的:

SELECT
    goods.id,
    goods.num,
    shop.reputation
FROM
    goods
    INNER JOIN shop
        ON goods.shop_id = shop.id
ORDER BY
    goods.num DESC,
    shop.reputation DESC

这两张表只进行了逻辑关联,没有建立外键。上面的SQL查询怎么通过django ORM实现?

阅读 13.8k
2 个回答

找到了一个解决方案,参考这篇博文
重点是django中的ForeignKey与数据库中FOREIGN KEY约束并不一样,ForeignKey是一种逻辑上的关联关系,我们可以指定是否使用数据库中的外键约束。

对于上面的两个Model,可以改写成这样:

class Goods(models.Model):
    """商品表"""
    name = models.CharField('名称', max_length=50)
    num = models.IntegerField('数量', default=0)
    # db_contraint=False表明了使用逻辑上的关联关系,而不需要数据库中的外键约束
    shop_id = models.ForeignKey('Shop', on_delete=models.CASCADE, db_contraint=False)

class Shop(models.Model):
    """店铺表"""
    name = models.CharField('店铺名称', max_length=50)
    reputation = models.SmallInteger('店铺信誉', default=1, help_text='范围:1~5')

这样就可以通过外键来实现INNER JOIN查询:
queryset = Goods.objects.values('id', 'num', 'shop__reputation').order('-num', '-shop__reputation')

Goods.objects.all().extra(
    select={'reputation': 'shop.reputation'},
    tables=['shop'],
    where=['goods.shop_id=shop.id']
)
.order_by(['-num', '-reputation'])
.values('id', 'num', 'reputation')
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题