如何将反向关系值作为列表获取
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
假设我有一些这样的模型。
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