2016-12-01 6 views
1

DateTimeFieldで2つのモデルを結合するにはどうすればいいですか?Django:DateTimeFieldに参加

class ExchangeRate(models.Model): 
    date = models.DateTimeField(...) 
    usd_rub = models.DecimalField(...) 

class LedgerEntry(models.Model): 
    account = models.ForeignKey(...) 
    date = models.DateTimeField(...) 
    amount = models.DecimalField(...) 

ここに私が望むものの例があります。 ExchangeRateテーブルのレコードには任意の日時があります(LedgerEntryテーブルの日付に対応していません)。それはちょうど、日付や時間のExchangeRatesに参加しても大丈夫です私はちょうどデータベースからすべてのこれらのオブジェクトを照会し、Pythonでそれらを「参加する」ことを理解

 ExchangeRate      LedgerEntry    
–––––––––––––––––––––––––––- –––––––––––––––––––––––––––--------- 
|  Date  | USD_RUB | | account |  Date  | Amount | 
|---------------|----------| |–––––––––|---------------|--------| 
| 29 Nov, 14:15 | 100.00 | | 13 | 29 Nov, 14:40 | 10.0 | 
| 29 Nov, 14:04 | 200.00 | | 37 | 29 Nov, 14:45 | 11.0 | 
| 29 Nov, 13:51 | 150.00 | | 19 | 01 Oct, 10:32 | 12.0 | 
| ............. | .........| –––––––––––––––––––––––––––--------- 
| 01 Oct, 10:23 | 500.00 | 
–––––––––––––––––––––––––––- 

          Join result        
–––––––––––––––––––––––––––------------------------------------- 
| account |  Date  | Amount | USD_RUB | USD_RUB amount | 
|–––––––––|---------------|--------|----------|----------------| 
| 13 | 29 Nov, 14:40 | 10.0 | 100.00 | 1000.0  | 
| 37 | 29 Nov, 14:45 | 11.0 | 100.00 | 1100.0  | 
| 19 | 01 Oct, 10:32 | 12.0 | 500.00 | 6000.0  | 
–––––––––––––––––––––––––––------------------------------------- 

(分、秒、などを無視しても安全です) 。データベースには数千ものレコードがあるので、これは、台帳エントリの対応する為替レートを探す際に、膨大な量の単一選択ステートメントを生成するので、実際には非効率的です。

答えて

0

最初に私は左を作ることを考えていたが、生のSQLを使用して参加し、私はextra()を使用して解決策を考え出した:

referral_profits = LedgerEntry.objects.filter(
    balance=request.user.balance, 
    reason=LedgerEntry.REASON_DEBIT 
).extra(
    select={ 'usd_value': r''' 
     SELECT usd_rub 
     FROM stats_exchangerate 
     WHERE 
      date_trunc('hour', billing_ledgerentry.date) = 
      date_trunc('hour', stats_exchangerate.date) 
     LIMIT 1 
     ''' 
    }, 
) 
for x in referral_profits: 
    print(x, x.usd_value, x.date) 

date_truncはPostgresの-speficic関数であることに注意してください。

編集:それはうまくいきますが、それはひどく非効率です。最後の手段は純粋なSQLを使用するように見えますか?