我有一个表,它有一个主键,我想在该主键上查询该表。这链接到 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)