如何将反向关系值作为列表获取

时间:2015-02-05 15:28:25

标签: django django-models django-orm

假设我有一些这样的模型。

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]},
 ]

我怎样才能有效地做到这一点,因为可能有数百或数千名员工。

2 个答案:

答案 0 :(得分:0)

您可以将related_name添加到外键。所以EmployeeFK = models.ForeignKey(Employee, related_name='projects')。然后,一旦有了Employee实例,就可以employee.projects.all()获取与该员工相关的所有项目。为你的部门模型做同样的事情。

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]}

我重复了五次这个程序,每次卸载管理shell都是新鲜的。拉动所有1000名员工,获得他们的项目和部门以及创建词典所需的平均时间在五次运行中每次都不到3秒。请注意,这是使用sqlite,而不是以大规模速度而闻名(尽管SSD确实有帮助)。

答案 1 :(得分:0)

class College(CommonFields):
    address = models.CharField(max_length=100)
    fees = models.IntegerField()

class Department(CommonFields):
    strength = models.IntegerField(default=60)
    college = models.ForeignKey(College, on_delete= models.CASCADE, related_name= "dept")

college.dept.all()

def make_dict(college, department):
    result = {'College Name': college.name}
    result['dept_id'] = [d.id for d in dept]
    result['dept_name'] = [d.name for d in dept]
    return result

def create_structure():
    result = [make_dict(e, e.dept.all()) for e in College.objects.all()]
    return result

I am getting an error 
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 41, in <module>
NameError: name 'college' is not defined