Django и Pandas - Создание объекта из поля Foreying Key
Я пытаюсь создать объекты, импортируя данные из excel с помощью pandas, а затем создавая объекты с помощью django.
Но я получаю сообщение об ошибке:
Запрос на соответствие активам не существует.
Мои модели
class Asset(models.Model):
ticker = models.CharField(max_length=255, unique=True)
class Transaction(models.Model):
id = models.AutoField(primary_key=True)
OrderChoices = (
('Buy', 'Buy'),
('Sell', 'Sell'),
)
date = models.DateField(("Date"), default=date.today)
order = models.CharField(max_length = 8, choices = OrderChoices)
asset = models.ForeignKey(Asset, on_delete=models.CASCADE, default=1)
shares_amount = models.FloatField()
share_cost = models.FloatField()
А вот код моего файла обновления:
class Command(BaseCommand):
def handle(self, *args, **options):
excel_file = "orders.xlsx"
df_2 = pd.read_excel(excel_file)
df_2 = df_2[['Date(UTC)','Pair', 'Type', 'Order Amount', 'AvgTrading Price']]
df_2.columns = ['date', 'asset', 'order', 'shares_amount','share_cost']
df_2['date'] = df_2['date'].str[:9]
df_2['asset'] = df_2['asset'].str.replace('USDT', '')
df_2['order'] = df_2['order'].str.replace('BUY', 'Buy')
print(df_2['asset'])
for index, row in df_2.iterrows():
try:
Transaction.objects.create(
date = datetime.date.today(),
order = df_2['order'] ,
asset = Asset.objects.get(ticker = df_2['asset']),
shares_amount = df_2['shares_amount'],
share_cost_brl = df_2['share_cost'],
)
except Exception as e:
print(f' Key Exception - {e}')
pass
Когда я пытаюсь print(df_2['asset']), я получаю в качестве результата список с id (из индекса pandas) и тикером
Я не знаком с Pandas, но чтобы asset = Asset.objects.get(ticker = df_2['asset']), работал, вам нужно получить из него доступ к единственному значению тикера.
Полагаю, это будет что-то вроде:
asset = Asset.objects.get(ticker = df_2['asset'].values[row_idx])
например:
ticker_value = df_2['asset']values[0]
asset = Asset.objects.get(ticker=ticker_value)
Нашел ошибку, она заключалась в том, как получить одно значение поля, вместо использования df_2['field'] получался индекс и поле, чтобы получить только поле без индекса, я должен использовать df_2.loc[index]['field']
Также я сделал некоторые обходные пути, чтобы получить asset_id вместо asset
Как это получается в итоге:
for index, row in df_2.iterrows():
try:
Transaction.objects.create(
date = datetime.date.today(),
order = df_2.loc[index]['order'] ,
asset_id = df_3.loc[index]['id'],
shares_amount = df_2.loc[index]['shares_amount'],
share_cost_brl = df_2.loc[index]['share_cost_usd'],
)
except Exception as e:
print(f' Key Exception - {e}')
pass
Вот обходной путь для получения id, не знаю, лучшее ли это решение, но я решил пойти этим путем, чтобы сделать создание объекта более простым:
# changed the index of df_2
df_2['order'] = df_2['order'].str.replace('BUY', 'Buy')
df_2 = df_2.set_index('ticker')
# got the assets from the django app with id, set the ticker as index also and merged both tables using the ticker as index
queryset = Asset.objects.values_list('id', "ticker")
df = pd.DataFrame(list(queryset), columns=['id',"ticker"])
df = df.set_index('ticker')
# print(df)
df_3 = df_2.merge(df, left_on="ticker",right_on="ticker",how='inner').set_axis(df_2.index)