2016-12-12 113 views
4

說我有這樣的模型在Django:獲取相關對象的某些領域在Django

class User(models.Model): 
    name=models.CharField(...) 
    email=models.EmailField(...) 
    photo=... 
    <other fields> 

class Comment(models.Model): 
    user=models.ForeignKey(User, ...) 

我有收到評論的對象和需求只是名稱和電子郵件字段發送電子郵件的功能(這只是例子,明顯)

def sendEmail(comment): 
    name, email=comment.user.name, comment.user.email 

在執行上面介紹,Django會獲取相關對象的用戶(東西約等於select * from users where id=comment.user_id) 的所有領域使用values_list我可以賣到只需要字段:

Users.objects.filter(id=comment.user_id).values_list('name', 'email')

但values_list只適用於QuerySet對象,不適用於模型實例。 我的問題是:有沒有什麼辦法只使用「評論」對象做同樣的事情? 它必須等於 select name, email from users where id=comment.user_id通過複雜(我不想傳輸大量存儲在網絡上時,我並不需要它的一些領域的數據)

+1

因此,在短期,你想的'ForeignKey'獲取相關對象只部分不需要*顯式* queryset? – dhke

+0

@dhke,是的,完全是 – fantom

+0

坦率地說:Hand'Comment'是一個返回上述查詢結果的屬性。我提出的其他解決方案最終都會通過自定義[ForwardManyToOneDescriptor](https://github.com/django/django/blob/8db6a6c0a1c73bf08e71e00d4ab8c4af3c5f0cb8/django/db/models/fields/related_descriptors.py#)在'contribute_to_class() L78),這只是矯枉過正。 – dhke

回答

2

如果你想有一些額外的用戶評論數據,而無需檢索整個User對象,我相信這是更好地獲取額外的數據時,您將獲取評論:

Comment.objects.filter(user=user).values_list('user__name', 'user__email') 

很明顯,你可以獲取其他有用Comment領域。

OR:

Comment.objects.filter(user=user).annotate(author_name=F('user__name'),\ 
              author_email=F('user__email')) 

這仍然使用QuerySet API,但是這兩種方法讓您跨越的關係,以獲得額外的數據,而無需額外的查詢。

0

複雜度必須等於select name, email from users where id=comment.user_id

什麼是真的等同於這個查詢是你已經擁有:

Users.objects.filter(id=comment.user_id).values_list('name', 'email') 

...但values_list只適用於QuerySet對象,而不是實例模型。

這是絕對正確的。但你需要考慮的是,一旦你有這樣的查詢集,你可以得到的第一要素,因爲與一個用戶ID有也只是一個用戶:

name, email = Users.objects.filter(id=comment.user_id).values_list('name', 'email').first() 
+0

一起使用'first'和tuple擴展是一個壞主意......如果沒有匹配,那麼你會得到一個錯誤,因爲它不能將'None'分成兩部分。 – Shadow