Объедините 2 модели django на основе нескольких столбцов без использования select_related
У меня есть 2 модели, обе из которых содержат 2 столбца, которые можно рассматривать как ключи, и третий столбец, который является значением
Целью является внутреннее соединение обеих моделей, но почему-то у меня возникают проблемы с этим
Я пытался следовать этой ссылке, но я не думаю, что в моем случае я хочу, чтобы столбцы были внешним ключом для других, поэтому я не могу использовать "select_related"
Мои модели следующие:
class AssetReturnTs(models.Model):
data_date = models.DateTimeField()
asset = models.ForeignKey(Asset, on_delete=CASCADE)
return = models.DecimalField(max_digits=19, decimal_places=10, null=True)
class Meta:
db_table = "return"
class AssetWeightTs(models.Model):
data_date = models.DateTimeField()
asset = models.ForeignKey(Asset, on_delete=CASCADE)
weight = models.DecimalField(max_digits=19, decimal_places=10, null=True)
class Meta:
db_table = "weight"
Я хочу сделать запрос, который объединяет AssetReturn и AssetWeight по data_date и asset_id. Конечной целью является взвешенная сумма доходности.
Запрос должен выглядеть следующим образом:
data_date | asset_id | weight | return
---=----- | -------- | ------ | -------
В настоящее время я делаю оба запроса по отдельности, конвертирую их в pandas и объединяю. Это выглядит следующим образом:
asset_return_ts = AssetReturnTs.objects.get_returns(start_date, end_date, asset_list).values(*columns_required)
asset_weight_ts = AssetWeightTs.objects.get_weights(start_date, end_date, asset_list).values(*columns_required2)
# Convert to df
merged_df = pd.merge(left=asset_return_ts_df, right=asset_weight_ts_df, on=['data_date', 'asset_id'], how='inner')
Любое решение, которое сводит 2 отдельных запроса к одному и помогает вычислить взвешенную сумму, будет высоко оценено
а Subquery
с OuterRef
в аннотации может помочь вам в этом.
Что-то вроде:
weights_subquery = AssetWeightTs.objects.filter(
data_date=OuterRef('data_date'),
asset_id=OuterRef('asset_id')
).values("weight")[:1]
return_query = AssetReturnTs.objects.annotate(
weight=Subquery(weights_subquery)
)
Это даст вам все 4 значения, которые вы хотите получить в каждом объекте return_query