为了账号安全,请及时绑定邮箱和手机立即绑定

Django 模型降序/嵌套查询

Django 模型降序/嵌套查询

繁星coding 2023-12-09 17:20:20
我无法理解如何使用 Django 中的表/模型结构来执行有用的查询。我想做的是:给定 Show 对象的主键,获取演出中所有字符的集合。我的模型如下:class Location(models.Model):    identifier = models.CharField(max_length=200)    def __str__(self):        """String for representing the Model object."""        return self.identifierclass Character(models.Model):    identifier = models.CharField(max_length=200)    def __str__(self):        """String for representing the Model object."""        return self.identifierclass Show(models.Model):    name = models.CharField(max_length=200)    shorthand = models.CharField(max_length=2, unique=True)    def __str__(self):        """String for representing the Model object."""        return self.shorthandclass Season(models.Model):    number = models.IntegerField()    show = models.ForeignKey(Show, on_delete=models.SET_NULL, null=True, related_name="seasons")    class Meta:        unique_together = (("number", "show"))    def __str__(self):        """String for representing the Model object."""        return (str(self.show) + "s" + str(self.number))class Episode(models.Model):    number = models.IntegerField()    season = models.ForeignKey(Season, on_delete=models.SET_NULL, null=True, related_name="episodes")    class Meta:        unique_together = (("number", "season"))    def __str__(self):        """String for representing the Model object."""        return (str(self.season) + "ep" + str(self.number))这看起来很基本,但我还没有破解如何通过外键回溯或其他方法来下降模型。我尝试过使用prefetch_lated但我想我对什么是 QuerySet 与对象感到困惑。我因需要执行的降序调用数量而推迟,Django 中肯定有更紧凑/简洁的方法吗?我还考虑过向角色模型添加外键,但很确定我最终会遇到同样的问题。
查看完整描述

1 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超2个赞

使用您拥有的模型,您需要将过滤器中的多个查找链接在一起:


characters = Character.objects.filter(scenes__episode__season__show_id=show_id)

话虽这么说,我建议稍微修改一下您的架构,因为这个查询非常昂贵。


如果您将 a 添加ManyToManyField到Show模型(并填充表),则会将此查询转换为简单的M2M查找:


class Show(models.Model):

    characters = models.ManyToManyField(Character)

    ...


characters = Show.objects.get(id=show_id).characters.all()

对于 而言prefetch_related,它只是一种防止多次数据库命中的优化。


第一个查询分别访问数据库 4 次,但如果添加预取:


characters = Character.objects.prefetch_related(

    'scenes', 'episode', 'season', 'show'

).filter(scenes__episode__season__show_id=show_id)

它只访问数据库一次,并在 python 中完成所有连接。


查看完整回答
反对 回复 2023-12-09
  • 1 回答
  • 0 关注
  • 53 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信