Django Queryset 过滤器等效于 SQL

Django Queryset filter equivalency to SQL

对我来说,不清楚或缺少示例代码来理解有关如何在 Django ORM 中内部使用 SQL 语言的文档。

我的 SQL 是:

SELECT projects_category.id, projects_category.name, projects_project.name
FROM projects_category
    JOIN projects_project_categories
        ON projects_category.id = projects_project_categories.project_id
    JOIN projects_project
        ON projects_project_categories.project_id=projects_project.id
            WHERE NOT projects_project.is_mini ORDER BY projects_category.id;

如何在 Django ORM 或 Django 视图中做同样的事情? 我已经尝试过滤和排除(可能使用了错误的参数......)但它似乎没有根据输出工作。除了这两个,可能还有更多选择。

此外,任何其他技巧都值得赞赏。

我的相关型号如下:

class Project(models.Model):
    name = models.CharField(max_length=100)
    is_mini = models.BooleanField(default=False)
    categories = models.ManyToManyField('Category', blank=True)

    def __str__(self):
        return self.name

class Category(models.Model): # will be used for search
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

我想获取包含类别集的查询集,类别集包含非迷你的项目集

为了完成这个请求,我建议按以下方式进行:

Project.objects.values('name','categories__name','categories__id').filter(is_mini=False).order_by('id')

.values 允许您从项目对象中选择要 select 的列。由于它与“类别”具有多对多关系,您可以使用关键字 'categories__field'.

访问这些类别的数据

几个不同表现的例子:

一般查询集

Project.objects.filter(is_mini=False).order_by('categories__id')

只需要值

Project.objects.only("name", "categories__name", "categories__id").filter(
    is_mini=False
).order_by('categories__id')  

预取类别 + 值

您可以将此答案与@Midoki 的答案结合起来,并使用 values 而不是 only 甚至 values_listDoc is here

Project.objects.values("name", "categories__name", "categories__id").filter(
    is_mini=False
).prefetch_related("categories").order_by("categories__id")

当您使用 ManyToMany 字段时(如果这里有很多行),您可以让 Django ORM 预取 categories 以提高性能。 Docs is here