Django фильтр в другой модели без внешнего ключа
У меня есть две разные модели:
class AggUii(Model):
year = models.IntegerField(blank=True, null=True)
month = models.CharField(max_length=2, blank=True, null=True)
country = models.CharField(max_length=7, blank=True, null=True)
service = models.CharField(max_length=16, blank=True, null=True)
doc_id = models.CharField(max_length=100, blank=True, null=True)
counts = models.IntegerField(blank=True, null=True)
data_type = models.CharField(max_length=200, blank=True, null=True)
section_type = models.CharField(max_length=200, blank=True, null=True)
yop = models.CharField(db_column='YOP', max_length=4, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'agg_uii'
class HierarchieIndexDocid(Model):
ancestor = models.CharField(max_length=255)
descendant_docid = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'hierarchie_index_docid'
Как видите, эти таблицы не связаны между собой внешним ключом. Поле doc_id в AggUii Model не является уникальным. И все же приведенный ниже запрос Mysql работает, выдавая правильные результаты.
Можно ли как-то перестроить этот оператор MySQL в Django ORM? В качестве параметра передается meta_id.
SELECT agg_uii.year, SUM(agg_uii.counts) FROM agg_uii,hierarchie_index_doc_id WHERE (agg_uii.doc_id=hierarchie_index_doc_id.descendant_docid and hierarchie_index_docid.ancestor="meta_id") GROUP BY agg_uii.year;
Спасибо!
class AggUii(Model):
# .
doc_id = models.CharField(max_length=100, blank=True, null=True, unique=True)
# .
class Meta:
managed = False
db_table = 'agg_uii'
class HierarchieIndexDocid(Model):
ancestor = models.CharField(max_length=255)
descendant = models.ForeignKey(
AggUii,
to_field='doc_id',
db_column='descendant_docid',
blank=True,
null=True,
on_delete=models.PROTECT,
)
class Meta:
managed = False
db_table = 'hierarchie_index_docid'
Тогда мы можем запросить:
from django.db.models import Sum
AggUii.objects.filter(hierarchieindexdocid__ancestor='meta_id').values(
'year'
).annotate(total=Sum('counts')).order_by('year')
Вот как я решил эту проблему:
from django.db.models import Q, Subquery
Я сделал следующий запрос:
doc_id_hier_qs = HierarchieIndexDocid.objects.filter(~Q(descendant_docid=""),ancestor=meta_id).values('descendant_docid')
После этого я использовал метод Subquery в Django:
invyearsqs_sq = AggUii.objects.force_index("idx_doc_id").filter(doc_id__in=Subquery(doc_id_hier_qs.values("descendant_docid"))).values('year').annotate(invSumYr = Sum('counts'))
Работает как шарм!