我的项目中有4个模型。它们是:
class Company(Group):
address_1 = models.CharField(max_length = 300, blank = True, null = True)
web_site = models.URLField(blank = True, null = True)
office_number = models.CharField(max_length = 20, blank = True, null = True)
class Person(models.Model):
user = models.ForeignKey(User)
company = models.ForeignKey(Company)
class Project(models.Model):
name = models.CharField(max_length = 100)
person = models.ManyToManyField(User, through = 'UserProject')
class UserProject(models.Model):
user = models.ForeignKey(User)
project = models.ForeignKey(Project)
is_owner = models.BooleanField(default = False)
在某种程度上,我想得到
- 与请求相关的所有项目。user
- 从事这些项目的公司
- 以及这些公司的员工
我试着写了一些代码,但查询并不精确。我们将不胜感激!
-
所有与request.user相关的项目都很简单,当然:
Project.objects.filter(person=request.user)
-
从事这些项目的公司必然需要你循环浏览这些项目:
for p in projects: p.company_set.all()
-
User
和Company
之间没有关系,也没有Company
上的任何其他外键,所以我不知道"员工"的概念从哪里来,也不知道如何得到它。
由于这是非常基本的东西,我假设您的问题在于生成的1*N个查询。在Django(1.3.1)的当前版本中,没有办法进一步优化。在Django 1.4中,有一个prefetch_related
,它将允许您选择使用Projects
的所有公司(和员工)。然而,它仍然需要对每个关系进行唯一的查询,因此总共需要3个查询才能获得项目、公司和员工。它是这样工作的:
Project.objects.filter(person=request.user).prefetch_related('company')
与此同时,我在使用django批处理选择方面取得了一些成功,它基本上试图模仿prefetch_related
的行为。
确定模型中的一些错误:
- Project通过UserProject在用户上有一个M2M,这很好,但我认为你的意思是让它在用户上拥有一个FK到用户的M2M
- 其次,你还没有和公司建立任何关系。在修复该错误之前,无法执行列表中的第2项
- 为什么公司要扩大集团?我一定是错过了什么
- 没有员工模型
示例:
class Company(models.Model):
address_1 = models.CharField(max_length = 300, blank = True, null = True)
web_site = models.URLField(blank = True, null = True)
office_number = models.CharField(max_length = 20, blank = True, null = True)
class Employee(models.Model):
user = models.ForeignKey(User)
company = models.ForeignKey(User)
class Project(models.Model):
name = models.CharField(max_length = 100)
employees = models.ManyToManyField(Employee, through = 'EmployeeProject')
companies = models.ManyToManyField(Company)
class EmployeeProject(models.Model):
employee = models.ForeignKey(Employee)
project = models.ForeignKey(Project)
is_owner = models.BooleanField(default = False)
并且在视图中
# all of the projects for a user (assuming employee field is supposed to M2M to the Employee model
projects = Project.objects.filter(employees__user=request.user)
for project in projects :
# assuming that there was some connection between project and company (there isnt currently, see me list of bugs with your models)
for company in project.companies_set.all() :
# There is no employee model, but if there was
employees = company.employees_set.all()
我已经考虑并使用了上面列出的一些解决方案,但没有什么是我想要的。对我来说,以下代码运行良好
projects = Project.objects.filter(person = request.user)
user_projects = UserProject.objects.filter(project__in = projects)
for user_project in user_projects:
person = user_project.user.get_profile()
company.append(person.company)
people.append(person)
company = set(company)