简化我的 Django 查询逻辑

发布于 2024-12-09 00:29:34 字数 2475 浏览 1 评论 0原文

我有一张看起来像这样的桌子。

+----+--------+---------+-----------+------------------------+
| id | parent | type    | libTypeId | name                   |
+----+--------+---------+-----------+------------------------+
|  2 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_hvt |
|  5 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_hvt |
|  8 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_hvt |
| 11 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_hvt |
|  3 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_lvt |
|  6 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_lvt |
|  9 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_lvt |
| 12 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_lvt |
|  1 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_svt |
|  4 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_svt |
|  7 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_svt |
| 10 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_svt |
| 13 |      2 | project |         2 | 065nm_GPIO             |
| 17 |      2 | project |         4 | 065nm_GPIO             |
| 14 |      2 | project |         6 | 065nm_GPIO             |
| 18 |      2 | project |        12 | 065nm_GPIO             |
| 15 |      2 | project |        16 | 065nm_GPIO             |
| 16 |      2 | project |        21 | 065nm_GPIO             |
| 19 |      2 | project |         2 | 065nm_Specialized      |
+----+--------+---------+-----------+------------------------+

我正在寻找的是一个查询,它会产生一个列表,其中我们获取 id = 1 的所有项目,该项目仅按名称、libtypeid 和第一个 libtypeid 排序。

换句话说,我应该得到这样的结果:

+----+--------+---------+-----------+------------------------+
| id | parent | type    | libTypeId | name                   |
+----+--------+---------+-----------+------------------------+
|  2 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_hvt |
|  3 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_lvt |
|  1 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_svt |
+----+--------+---------+-----------+------------------------+

现在我可以走到这一步,但我怎样才能只得到第一个?

Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')

然后我进一步这样做。

full = Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')
names, out = [], []
for v in full:
    if v.name not in names:
       out.append(v)
       names.append(v.name)
return out

如果有人可以清理一下,我将非常感激。

I have a table which looks like this.

+----+--------+---------+-----------+------------------------+
| id | parent | type    | libTypeId | name                   |
+----+--------+---------+-----------+------------------------+
|  2 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_hvt |
|  5 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_hvt |
|  8 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_hvt |
| 11 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_hvt |
|  3 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_lvt |
|  6 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_lvt |
|  9 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_lvt |
| 12 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_lvt |
|  1 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_svt |
|  4 |      1 | project |         6 | 1p6m4x0y1z_1.2-1.8_svt |
|  7 |      1 | project |        16 | 1p6m4x0y1z_1.2-1.8_svt |
| 10 |      1 | project |        21 | 1p6m4x0y1z_1.2-1.8_svt |
| 13 |      2 | project |         2 | 065nm_GPIO             |
| 17 |      2 | project |         4 | 065nm_GPIO             |
| 14 |      2 | project |         6 | 065nm_GPIO             |
| 18 |      2 | project |        12 | 065nm_GPIO             |
| 15 |      2 | project |        16 | 065nm_GPIO             |
| 16 |      2 | project |        21 | 065nm_GPIO             |
| 19 |      2 | project |         2 | 065nm_Specialized      |
+----+--------+---------+-----------+------------------------+

What I am looking for is a query which results in a list where we get all projects with id = 1 which is sorted by name, libtypeid and the FIRST libtypeid only.

In otherwords I should end up with this:

+----+--------+---------+-----------+------------------------+
| id | parent | type    | libTypeId | name                   |
+----+--------+---------+-----------+------------------------+
|  2 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_hvt |
|  3 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_lvt |
|  1 |      1 | project |         2 | 1p6m4x0y1z_1.2-1.8_svt |
+----+--------+---------+-----------+------------------------+

Now I can get this far but how do I get only the first one??

Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')

I then further do this..

full = Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')
names, out = [], []
for v in full:
    if v.name not in names:
       out.append(v)
       names.append(v.name)
return out

Much appreciate if someone can clean this up a bit..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北城挽邺 2024-12-16 00:29:34

如果我正确理解了这个问题,您需要对您的集合进行“分组”并返回每组的第一行。您需要查看聚合: https://docs.djangoproject.com /en/dev/topics/db/aggregation/

类似的东西
<代码>

Variant.objects
    .values('name', 'libtype_id')
    .annotate(min_libtype_id=Min('libtype_id'))
    .filter(parent=self.id)

this is untested.

if I understand the question correctly, you need to "group by" your set and return the first row from each group. you need to take a look at aggregation: https://docs.djangoproject.com/en/dev/topics/db/aggregation/

something along the lines of

Variant.objects
    .values('name', 'libtype_id')
    .annotate(min_libtype_id=Min('libtype_id'))
    .filter(parent=self.id)


this is untested.

我还不会笑 2024-12-16 00:29:34

您可以将 [number] 添加到查询集中,例如:

Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')[0]

返回查询集中的第一条记录。要获得最后一个,它将是 [:0],冒号反转拼接。

You can add [number] to the queryset, like:

Variant.objects.filter(parent=self.id).order_by('name', 'libtype_id')[0]

That returns the first record in the queryset. To get the last one, it would be [:0], the colon reverses the splice.

不顾 2024-12-16 00:29:34

这是我一直在寻找的答案。

class VariantQuerySet(QuerySet):
    def as_single_library_type(self):
        query = self.filter().query
        query.group_by = ['name']
        return QuerySet(self.model, using=self._db, query=query)

class VariantManager(models.Manager):

    def get_query_set(self):
        return VariantQuerySet(self.model, using=self._db)

这基本上会执行默认的 GROUP BY ,它将所有内容减少到我需要的内容。感谢所有尝试回答的人!

Here is the answer I was looking for..

class VariantQuerySet(QuerySet):
    def as_single_library_type(self):
        query = self.filter().query
        query.group_by = ['name']
        return QuerySet(self.model, using=self._db, query=query)

class VariantManager(models.Manager):

    def get_query_set(self):
        return VariantQuerySet(self.model, using=self._db)

This basically does a default GROUP BY which reduces everything to what I need. Thanks to all who attempted answered!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文