【问题标题】:Full join ManyToMany field Django完全加入多对多字段 Django
【发布时间】:2018-07-25 18:26:24
【问题描述】:

全部)。我使用 Django 2.0 编写项目。我有 2 个模型:合作者和部门(1 个合作者可以在一个或多个部门工作)。所以,我想查询如下表:

|                | Department 1 | Department 2 | Department 3 |
|:---------------|:------------:|:------------:|:------------:|
| Collaborator 1 |     True     |     False    |     False    |
| Collaborator 2 |     True     |     False    |     True     |
| Collaborator 3 |     True     |     True     |     True     |
  • 协作者包含first_namelast_name
  • 如果合作者在这个部门工作,则为真。
  • 如果合作者不在该部门工作,则为 false。

我希望对数据库的请求数量最少,但没有更好的方法:使用 raw/execute 或其他 django-orm 方法?

models.py

class Department(models.Model):
    """Model that represents department information."""

    title = models.CharField(max_length=256)


class Collaborator(models.Model):
    """Model that represents collaborator information."""

    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)
    ...
    departments = models.ManyToManyField(Department)

【问题讨论】:

    标签: sql django django-orm


    【解决方案1】:

    我只是使用一个连接表,我发现使用manytomany的优势很小,然后你只需查询连接

    class Department(models.Model):
        """Model that represents department information."""
    
        title = models.CharField(max_length=256)
    
    class DepartmentCollaboratorJoin(models.Model):
        """Model that represents join."""
    
        department = models.ForeignKey("Department")
        collaborator = models.ForeignKey("Collaborator")
        joininfo = models.CharField(max_length=256)
    
    class Collaborator(models.Model):
        """Model that represents collaborator information."""
    
        first_name = models.CharField(max_length=128)
        last_name = models.CharField(max_length=128)
    

    【讨论】:

    • ManyToManyField 为您隐式执行此操作。
    【解决方案2】:

    我找到了解决方案 - prefetch_related。它只调用 2 个查询,这就足够了。

    data_grid = {}
        for collab in Collaborator.objects.prefetch_related('departments'):
            full_name = f'{collab.first_name} {collab.last_name}'
            data_grid[full_name] = [depart.title for depart in collab.departments.all()]
    

    那么其他过滤器将由前端完成。

    【讨论】:

      猜你喜欢
      • 2019-02-01
      • 2013-04-27
      • 2011-02-05
      • 2021-11-20
      • 2016-02-23
      • 2012-03-25
      • 2011-05-25
      • 2020-10-28
      相关资源
      最近更新 更多