Django-ORM:说明对情况的精确查询

时间:2012-03-12 14:23:13

标签: django python-2.7 django-orm

我的项目中有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)

在视图中我想要

  1. 与request.user
  2. 相关的所有项目
  3. 正在开展这些项目的公司
  4. 以及这些公司的员工
  5. 我尝试编写一些代码,但查询不准确。帮助将不胜感激!

3 个答案:

答案 0 :(得分:0)

  1. 所有与request.user相关的项目都很简单,当然:

    Project.objects.filter(person=request.user)
    
  2. 从事这些项目的公司必然要求您循环完成这些项目:

    for p in projects:
        p.company_set.all()
    
  3. UserCompanyCompany上的任何其他外键之间没有任何关系,所以我不知道&#34的概念在哪里;雇员"来自或如何得到它。

  4. 因为,这是非常基本的东西,我假设您的问题是生成的1 * N个查询。在当前版本的Django(1.3.1)中,没有办法进一步优化它。在Django 1.4中,prefetch_related允许您使用Projects选择所有公司(和员工)。但是,它仍然需要对每个关系进行唯一查询,因此共有3个项目,公司和员工。它的工作原理如下:

    Project.objects.filter(person=request.user).prefetch_related('company')
    

    与此同时,我在使用django-batch-select方面取得了一些成功,它基本上试图模仿prefetch_related的行为。

答案 1 :(得分:0)

确定模型中的一些错误:

  • 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()    

答案 2 :(得分:0)

我已经思考并使用了上面提到的一些解决方案,但没有什么是我想要的。对我来说,下面的代码很好用

            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)