gpt4 book ai didi

Django 管理员 : show single instance of duplicate instances

转载 作者:行者123 更新时间:2023-12-02 03:06:11 34 4
gpt4 key购买 nike

我试图显示模型中的单个实例(数据库行),其中多个实例共享多行的相同字段(列)值。为了澄清这一说法,我有以下情况:

ID/Title/Slug/Modified
1 Car A 1s ago
2 Car A 2s ago
3 House B 1s ago

如果上面的小表是我的数据库,我希望我的 Django 管理页面根据我的 slug 字段(列)显示不同的行,显示最后编辑的版本(我还有另一列时间...所以上面的表将显示在管理页面中如下:

ID/Title/Slug/Modified
1 Car A 1s ago
3 House B 1s ago

虽然第 1 行和第 2 行有不同的 pk,但它们有相同的 slug,但稍后我只想要其中一个...

我可以在我的views.py中实现这一点,如下所示

existing_data = MyModel.objects.filter(slug=slug).latest('modified')

但那是因为我正在寻找 slug 的特定实例..如果我不是,我也可以使用 group_by...

我正在尝试在管理页面中显示此内容。我在模型管理器中尝试了以下技术,

class ModelManager(models.Manager):
def get_query_set(self):
return super(ModelManager, self).get_query_set().group_by('title')

但我收到此错误

'QuerySet' object has no attribute 'group_by'

然后我在读this part of the Django book他们在模型管理器中实现了原始 SQL,我尝试将其复制到我的情况,如下所示,

class ModelManager(models.Manager):
def uniques(self):
cursor = connection.cursor()
cursor.execute("""
SELECT *
FROM eventform_event
GROUP BY slug
""")
return [row[0] for row in cursor.fetchone()]

我是我的模特

objects = ModelManager()

我只是不确定如何让管理模型查看不覆盖 get_query_set 的自定义管理器。当我使用此自定义管理器覆盖 get_query_set 时,我收到此错误

'long' object has no attribute '__getitem__'

我也尝试过测试'values()、values_list()、distinct()等,但它们都给我错误...distinct()告诉我我的数据库(mysql)不支持此功能。现在确定我是否必须切换数据库才能实现此功能,现在我没有想法可以尝试......任何人都知道如何实现此功能......谢谢。

#

在我的 admin.py 页面中,我可以获得侧过滤器 (list_filter),以根据 this thread 显示基于 slug 列的唯一条目。推荐...

不幸的是,我无法让管理页面中显示的行使我的模型基于特定列是唯一的...

最佳答案

如果您将 Django 1.4+ 与 PostgreSQL 结合使用,则可以使用 queryset.distinct()带有 *fields 参数。如果您使用旧版本的 Django 或不同的数据库引擎,请告诉我,我将找到不同的方法。

如果你的模型看起来像这样:

from django.db import models

class TestModel(models.Model):
title = models.TextField(max_length=150)
slug = models.TextField(max_length=150)
modified = models.DateTimeField(auto_now=True)

然后您可以在 ModelAdmin 的 queryset 方法中执行此操作:

from django.contrib import admin

import models

class TestModelAdmin(admin.ModelAdmin):
list_display = ('title', 'slug', 'modified')

def queryset(self, request):
qs = super(TestModelAdmin, self).queryset(request)
qs = qs.order_by('slug', '-modified').distinct('slug')
return qs

admin.site.register(models.TestModel, TestModelAdmin)

希望有帮助。

编辑:好吧,如果你使用 MySQL,那就没那么整洁了。您不能使用原始 SQL,因为 Django 管理员希望使用 QuerySet 而不是 RawQuerySet。即使我们可以使用原始 SQL,它也不会像 GROUP BY slug 那么简单,因为如果你这样做,MySQL 会按照它们在表中出现的顺序给出结果。因此,如果您的数据如下所示:

+----+-------+------+---------------------+
| id | title | slug | modified |
+----+-------+------+---------------------+
| 1 | Car | A | 2013-06-30 20:18:06 |
| 2 | House | B | 2013-06-30 20:18:12 |
| 3 | Car | A | 2013-06-30 21:02:51 |
| 4 | Thing | C | 2013-06-30 22:08:00 |
| 5 | House | B | 2013-06-30 22:08:05 |
+----+-------+------+---------------------+

无论任何 order by 子句如何,按 slug 分组都会为您提供 id 1,2 和 4。我们实际上想要 ids 3、4 和 5,因为否则 Django 管理员将不会向我们显示最近修改的条目(这就是您所说的您想要的)。因此,在进行任何分组之前,我们必须从预先排序的表中进行选择。

我能想到的最好方法是将我为 PostgreSQL 提供的答案中的 queryset 方法更改为:

def queryset(self, request):
qs = super(TestModelAdmin, self).queryset(request)
qs = qs.extra(where=[
"id IN (
SELECT id FROM (
SELECT * FROM myapp_testmodel ORDER BY modified DESC
) AS last_modified
GROUP BY slug)"
])
return qs

您必须将 id 更改为表的主键名称,将 myapp_testmodel 更改为表的名称。

关于Django 管理员 : show single instance of duplicate instances,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17392433/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com