Django 查询 ORM 以基于主键进行查询,然后从由外键链接的联结表中获取信息



我有一个表,它有一个主键,我想在该主键上查询该表。这链接到 2 个连接表,这些连接表是链接到我的第一个表的外键。我是否可以从所有这些表中访问与此主键相关的所有信息:

models.py:

class Variant(models.Model):
variant = models.CharField(max_length=60, primary_key=True)

class VarSamRun(models.Model:
sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
run = models.ForeignKey(Run, on_delete=models.CASCADE, db_column='run')
.... 
more attributes
...

class ClinVarSam(models.Model:
sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
.... 
more attributes
...

我想用一些变量查询 VarSamRun,例如:

obj = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')

但我似乎无法从这个对象中获取来自 ClinVarSamRun 的任何信息

我也尝试过:

obj = Variant.objects.prefetch_related('variant__clinicallyreportedvariant_set', 'variantsamplerun_set')

但这又不包含任何 VarSamRun 或 ClinVarSamRun 对象属性

我怎样才能把这些拿出来?

更新的答案

根据您的评论,我想到了一个解决方案:

variants = Variant.objects.filter(variantsamplerun_set__sample=sample, variantsamplerun_set__run=run).values_list('variant', 'variantsamplerun_set__sample_id', 'clinvarsam_set__some_field', 'clinvarsam_set__other_field')
for v in variants:
print(v['variant'], v['variantsamplerun_set__sample_id'], v['clinvarsam_set__some_field'], v['clinvarsam_set__other_field'])

我认为values_list方法可能很好地实现您所追求的查询。 https://docs.djangoproject.com/en/1.11/ref/models/querysets/#values-list

旧答案

我认为您误解了select_related的使用,这将更改在评估查询集时对数据库进行的查询,而不是返回变体。 另外,你的意思是使用 .filter 还是 .get?.filter 返回的是 Queryset 而不是对象。

varsamrun_qs = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')
for varsamrun in varsamrun_qs:
print(varsamrun.variant)  # This does not make an extra sql call to retrieve the variant object

这应该创建一个 sql 查询来评估查询集并检索相关的变体字段,然后打印每个 VariantSampleRun 的变体。

如果您希望能够从匹配的 VarSamRun 中检索 ClinVarSam,则可以向 VarSamRun 模型添加一个属性方法:

class VarSamRun(models.Model:
sample = models.ForeignKey(Sample, on_delete=models.CASCADE, db_column='sample')
variant = models.ForeignKey(Variant, on_delete=models.CASCADE, db_column='variant')
run = models.ForeignKey(Run, on_delete=models.CASCADE, db_column='run')
.... 
more attributes
...
@property
def clinvarsam(self):
return ClinVarSam.objects.get(sample=self.sample, variant=self.variant)

然后在前面的示例中使用它:

varsamrun_qs = VariantSampleRun.objects.filter(sample=sample, run=run).select_related('variant')
for varsamrun in varsamrun_qs:
print(varsamrun.variant)  # This does not make an extra sql call to retrieve the variant object
print(varsamrun.clinvarsam)

相关内容

  • 没有找到相关文章

最新更新