2015-02-05 31 views
0

假設我有這樣的一些模型。如何獲得反向關係值列表

class Employee(models.Model): 
    FullName = models.CharField(max_lenth = 100) 

class Projects(models.Model): 
    EmployeeFK = models.ForeignKey(Employee) 
    ProjectName = models.CharField(max_length = 100) 

class Departments(models.Model): 
    EmployeeFK = models.ForeignKey(Employee) 
    DateJoined = models.DateField() 

我想得到我的輸出是這樣的。

[ 
    {"id" : 1 , "FullName" : "John Doe 1" , "projects_ids" : [1,2,3] , "departments_ids" : [1,2,5]} , 
    {"id" : 2 , "FullName" : "John Doe 2" , "projects_ids" : [17,18,20] , "departments_ids" : [6,2,5]}, 
] 

我該如何有效地做到這一點,可能有成百上千的員工。

+0

幾年前我有一個類似的問題 - 請參考這個獲得一個大概:http://stackoverflow.com/questions/12731897/group-by-foreign-key-and-show-related-items- django – karthikr 2015-02-05 15:55:27

+0

@karthikr你的解決方案是非常有用的,但因爲我需要獲取多個反向關係,並使用大型循環,我會遇到性能問題。 – SantaXYZ 2015-02-05 16:30:50

+0

@SantaXYZ,我修改了我的答案,看看。我基本上嘲笑了一堆虛擬數據,併爲時間查詢。 – paidhima 2015-02-06 03:40:27

回答

0

您可以將related_name添加到您的外鍵。所以EmployeeFK = models.ForeignKey(Employee, related_name='projects')。然後,一旦您擁有員工實例,您可以執行employee.projects.all()以獲取與該員工相關的所有項目。對你的Departments模型做同樣的事情。

def make_dict(employee, projects, departments): 
    result = {'id': employee.id, 'FullName': employee.FullName} 
    result['projects_ids'] = [p.id for p in projects] 
    result['departments_ids'] = [d.id for d in departments] 
    return result 

def create_structure(): 
    result = [make_dict(e, e.projects.all(), e.departments.all()) for e in Employee.objects.all()] 
    return result 

也許那會做你想要的嗎?我有一段時間沒有使用過Django,所以具體的語法可能會稍微偏離。

編輯:

正如你似乎是效率非常感興趣,我做測試的一點點。我使用我係統SSD上的sqlite3創建了一個虛擬項目/應用程序,其中包含您提供的模型。我囊括了1000名員工條目,10000個項目條目和5000個部門條目。我加載了所有的員工,然後隨機分配給他們的項目和部門。最後,我添加了上面給出的兩個程序(修改爲e.projects_set.all()e.departments_set.all(),因爲我完全保留了您的代碼)並放行。結果是1000個字典的列表,每個字典代表一名員工。一個例子,從第一個條目:

{'departments_ids': [4279, 4789], 'FullName': u'Jedidiah Strosin', 'id': 1, 'projects_ids': [1051, 1198, 1715, 2991, 3322, 4934]} 

我重複該過程五次,每次卸載管理外殼,所以它是新鮮的。拉動所有1000名員工,獲得他們的項目和部門以及創建字典所需的平均時間不到5分鐘。請注意,這是使用sqlite,並不完全以大規模速度而聞名(儘管SSD確實有幫助)。

+0

你是對的,但是因爲我需要以我解釋的格式得到結果,我需要運行大循環和許多查詢。 – SantaXYZ 2015-02-05 16:04:49

+0

添加related_name是無關緊要的:如果您沒有定義它,您仍然可以使用默認的相關名稱,例如project_set。 – 2015-02-05 16:45:31

+0

對,我不記得關係的完整語法,但'related_name'立即彈出了我的腦海。我喜歡明確的定義,但這不是必需的。 – paidhima 2015-02-05 18:51:52