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)

Вернуться на верх