python - 覆盖 Django RelatedManager 和 Queryset 以过滤通过模型中的字段
问题描述
我有两个模型通过第三个模型通过多对多字段链接。Through 模型中有一些额外的字段。我想覆盖 RelatedManager 以生成一些自定义查询集,这些查询集使用通过模型中的额外字段。需要注意的是,我的通过模型是使用定义额外字段的子类/mixin 创建的。我想要做的是获取与 SampleBatch 相关的所有 Gene 对象,这些对象在链接多对多字段的 SampleBatchGene 实例中具有 1 的活动状态:
In [1]: SampleBatch.objects.get(sample__lab_number="18_11998").genes.active()
Out[1]: <QuerySet [<Gene: BAP1>]>
这是我到目前为止所拥有的:
class SampleBatch(models.Model):
sample = models.ForeignKey(Sample, on_delete=models.CASCADE)
batch = models.ForeignKey(Batch, on_delete=models.CASCADE)
genes = models.ManyToManyField(
"Gene", through='SampleBatchGene', related_name='samplebatches',
blank=True, through_fields=('samplebatch', 'gene')
)
class Meta:
managed = True
db_table = 'sample_batch'
unique_together = (('sample', 'batch'),)
verbose_name_plural = "Sample batches"
def __str__(self):
return '{}-{}'.format(self.sample, self.batch)
class Gene(models.Model):
gene_id = models.BigAutoField(primary_key=True)
gene_name = models.CharField(unique=True, max_length=255, db_index=True)
hgnc_number = models.IntegerField(unique=True, db_index=True)
class Meta:
managed = True
db_table = 'gene'
def __str__(self):
return self.gene_name
class ActiveQuerySet(models.QuerySet):
def active(self):
return self.filter(active=1)
def inactive(self):
return self.filter(active=0)
class LinkMixin(models.Model):
ACTIVE_CHOICES = (
(0, 'Inactive'),
(1, 'Active')
)
activated = models.DateTimeField(default=timezone.now)
active = models.IntegerField(
choices=ACTIVE_CHOICES, default=1, db_index=True
)
created = models.DateTimeField(auto_now_add=True)
deactivated = models.DateTimeField(blank=True, null=True, default=None)
objects = models.Manager()
statuses = ActiveQuerySet.as_manager()
class Meta:
abstract = True
class SampleBatchGene(LinkMixin):
samplebatch = models.ForeignKey(SampleBatch, on_delete=models.CASCADE)
gene = models.ForeignKey(Gene, on_delete=models.PROTECT)
class Meta:
managed = True
db_table = 'sample_batch_gene'
unique_together = (('samplebatch', 'gene'), )
def __str__(self):
return '{}-{}'.format(self.samplebatch, self.gene)
尝试使用自定义反向管理器(根据文档)会出现以下错误:
In [5]: SampleBatch.objects.get(sample__lab_number="18_11998").genes.all()
Out[5]: <QuerySet [<Gene: BAP1>]>
In [6]: SampleBatch.objects.get(sample__lab_number="18_11998").genes.filter(samplebatchgene__active=1)
Out[6]: <QuerySet [<Gene: BAP1>]>
In [7]: SampleBatch.objects.get(sample__lab_number="18_11998").genes(manager="statuses").active()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-6-d8d95f5854b4> in <module>
----> 1 SampleBatch.objects.get(sample__lab_number="18_11998").genes(manager="statuses").active()
~/.pyenv/versions/3.6.6/envs/varDB/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py in __call__(self, manager)
848
849 def __call__(self, *, manager):
--> 850 manager = getattr(self.model, manager)
851 manager_class = create_forward_many_to_many_manager(manager.__class__, rel, reverse)
852 return manager_class(instance=self.instance)
AttributeError: type object 'Gene' has no attribute 'statuses'
编辑:Willem Van Onsem 提示:它正在尝试使用来自 的自定义管理器Gene
,但我已针对SampleBatchGene
. 所以我需要弄清楚如何从 Through Model 中指定自定义管理器。我曾希望通过 来完成这项工作,LinkMixin
这样我就不必在Many-To-Many
. 我想我可以将自定义管理器粘在两者上SampleBatch
并Gene
让它工作,但我有很多这种类型的关系使用LinkMixin
作为直通模型,所以希望以某种方式避免它。
解决方案
推荐阅读
- amazon-web-services - AWS CDK 使用自定义源将生命周期更新/添加到现有 S3 存储桶
- html - 更改选中时看起来像按钮的复选框的背景颜色
- java - 在Java中添加到列表后清除HashMap
- r - 您如何获得广义线性混合模型的上下置信区间?
- python-3.x - 如何通过python代码使用boto3更新aws cloud watch中的指标?
- flutter - 我可以用 TextEditingController 附加一个字符/表情符号吗
- javascript - 用样式化的 span 动态替换字符串中的单词
- ruby-on-rails - Rails - 包含模块:如果我们在类/控制器中包含多个模块,它会影响内存或性能吗?
- python - 用于为 api 调用创建 URL 的 fstring 出现“无效语法”错误
- css - 如何使用 Formfacade 添加自定义 css 以隐藏谷歌表单中的后退按钮