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

How to get reverse relationship values as a list

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

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

面对可能有数百或数千名员工,我如何才能高效地做到这一点。

您可以将 related_name 添加到您的外键。所以EmployeeFK = models.ForeignKey(Employee, related_name='projects')。然后,一旦您拥有 Employee 的实例,您就可以执行 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 创建了一个虚拟 project/app。我模拟了 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 确实有帮助)。

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