2011-12-30 16 views
3

嗨#1人,Django的:SQL查詢與模型函數不同

在我的當前項目

,我有以下的模型結構:

class Project(models.Model): 
    student_id = models.ForeignKey(User) 
    class_a = models.ForeignKey(ClassA) 
    class_b = models.ForeignKey(ClassB) 
    ... 

class ClassA(models.Model): 
    teacher_name = models.CharField(...) 

class ClassB(models.Model): 
    teacher_name = models.CharField(...) 

ClassA和ClassB的有很大的不同,只有他們才有共同的teacher_name,因此我將它保存在單獨的類中。 另外,在每個項目中只有class_a class_b可以包含一個ForeignKey(它不能被分配給兩個類)。

當我顯示所有的項目,我想列出老師的名字,所以我創建了一個小模型函數,該函數返回老師的名字:

def get_teacher_name(self): 
    if self.class_a: 
     return self.class_a.teacher_name 
    if self.class_b: 
     return self.class_b.teacher_name 

現在,我想編寫一個查詢其返回教師的名字爲student_id數據,只返回老師的名字一次,如: 對於學生X 項目教師 生物學X夫人 物理Y先生 ( - >數學Y先生應該被忽視)

我應該如何構造Django查詢?我想做 Project.objects.filter(student_id = user.pk).values('get_teacher_name')。distinct(),但這是不可能的。有沒有解決方案?

謝謝您的建議!

回答

3

而你卻被尋找valuesannotate https://docs.djangoproject.com/en/dev/topics/db/aggregation/#order-of-annotate-and-values-clauses

,這將給你唯一值的值調用。

import itertools 

class_a_names = user.project_set.values_list('class_a__teacher_name', flat=True).annotate() 
class_b_names = user.project_set.values_list('class_b__teacher_name', flat=True).annotate() 
unique_teachers = set(itertools.chain(class_a_names, class_b_names)) 
+0

謝謝你的回答。你能解釋一下project_set的來源嗎?謝謝! – neurix 2011-12-30 02:25:43

+0

@neurix - 如果你有一個'ForeignKey'從項目到'User',django以'class_set'的形式添加反向相關的模型管理器,除非你在'ForeignKey'字段中指定了'related_name'參數。 https://docs.djangoproject.com/zh/dev/topics/db/queries/#following-relationships-backward – 2011-12-30 02:40:09

+0

有沒有辦法將老師的pk保留在列表中?我嘗試過('class_a_teacher__name','class_a_teacher__pk'),但找不到pk。感謝您的幫助! – neurix 2011-12-30 02:40:39