[英]Django query ORM to query based on primary key then get information from junction tables linked by foreign key
我有一个具有主键的表,我想在该主键上查询该表。 这链接到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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.