2017-02-10 30 views
0

我有4個型號。如何連接多個模型並以pythonic方式獲得結果?

class User(models.Model): 
    id = models.IntegerField(primary_key=True) 
    name = models.CharField() 

class Subscription(models.Model): 
    user_id = models.ForeignKey(User) 
    title = models.CharField() 

class Address(models.Model): 
    user_id = models.ForeignKey(User) 
    street = models.CharField() 

class Wallet(models.Model): 
    user_id = models.ForeignKey(User) 
    balance = models.DecimalField(max_digits=6, decimal_places=2) 

在這裏我想獲得訂閱行以及尊重用戶地址和錢包餘額。有可能在單個查詢(ORM)中檢索嗎?

我聽說過select_related()prefetch_related()。但不知道如何把所有的東西放在一個查詢集中。

如何以pythonic方式實現此目的?

+0

像這樣的東西? 'User.objects.filter(id =?)。select_related('subscription','address','wallet')' –

+0

用戶表中沒有訂閱,地址和錢包的參考。以上字段是表格中唯一可用的字段。 :( –

+0

你可以用你的完整models.py更新你的問題嗎? –

回答

0

首先從FK字段中刪除_id。您仍然需要subscription.user_id(int)和subscription.user這就是User。現在你必須編寫subscription.user_id_id來訪問id。

你知道用戶可以有多個錢包和地址與你db設計?

使用ORM進行單個查詢是不可能的。但有可能在3個查詢中完成(無論多少記錄都無關緊要)。

更新:

class User(models.Model): 
     name = models.CharField() 

class Subscription(models.Model): 
     user = models.ForeignKey(User, related_name='subscriptions') 
     title = models.CharField() 

class Address(models.Model): 
     user = models.ForeignKey(User, related_name='addresses') 
     street = models.CharField() 

class Wallet(models.Model): 
     user = models.ForeignKey(User, related_name='wallets') 
     balance = models.DecimalField(max_digits=6, decimal_places=2) 


subscriptions = Subscription.objects.select_related('user').prefetch_related(
        'user__wallets', 'user__addresses') 

for s in subscriptions: 
    print(s.user.name) 
    for wallet in s.user.wallets.all(): 
     print(wallet.balance) 
    for address in s.user.addresses.all(): 
     print(address.street) 
+0

如果用戶應該有比移動FKS到用戶模型只是一個錢包和地址,並使用'select_related'一個查詢檢索的一切。 – Raz

+0

找不到用戶對象上的「wallet_set」,「user__wallet_set」是無效的參數prefetch_related() 沒有提及用戶模型中的電子錢包,我只參考了錢包模型中的用戶模型 感謝您通知「_id」和多個錢包f或一個用戶。 但我的核心問題依然存在:( –

+0

' _set'是ForeignKeys默認'related_name',但我更喜歡我現在做的隱含指定。檢查它。 – Raz

0

你有沒有試圖按照從文檔this snippet

有一個User對象實例,你可以做這樣的事情來訪問訂閱:

user.subscription_set.all() 

這將需要不同的管理人員單獨調用,雖然收集的所有數據。

相關問題