gpt4 book ai didi

django - 在 Django 中对多表继承进行注释

转载 作者:行者123 更新时间:2023-12-04 20:24:23 25 4
gpt4 key购买 nike

我有一个基本的 LoggedEvent 模型和许多子类模型,如下所示:

class LoggedEvent(models.Model):
user = models.ForeignKey(User, blank=True, null=True)
timestamp = models.DateTimeField(auto_now_add=True)

class AuthEvent(LoggedEvent):
good = models.BooleanField()
username = models.CharField(max_length=12)

class LDAPSearchEvent(LoggedEvent):
type = models.CharField(max_length=12)
query = models.CharField(max_length=24)

class PRISearchEvent(LoggedEvent):
type = models.CharField(max_length=12)
query = models.CharField(max_length=24)

用户在执行相关操作时会生成这些事件。我正在尝试生成每个用户在上个月引起的每种事件类型的数量的使用报告。我在 Django 的 ORM 上苦苦挣扎,当我接近时,我遇到了问题。下面是查询代码:
def usage(request):
# Calculate date range
today = datetime.date.today()
month_start = datetime.date(year=today.year, month=today.month - 1, day=1)
month_end = datetime.date(year=today.year, month=today.month, day=1) - datetime.timedelta(days=1)

# Search for how many LDAP events were generated per user, last month
baseusage = User.objects.filter(loggedevent__timestamp__gte=month_start, loggedevent__timestamp__lte=month_end)
ldapusage = baseusage.exclude(loggedevent__ldapsearchevent__id__lt=1).annotate(count=Count('loggedevent__pk'))
authusage = baseusage.exclude(loggedevent__authevent__id__lt=1).annotate(count=Count('loggedevent__pk'))

return render_to_response('usage.html', {
'ldapusage' : ldapusage,
'authusage' : authusage,
}, context_instance=RequestContext(request))

ldapusage 和 authusage 都是用户列表,每个用户都使用 .count 属性进行注释,该属性应该表示用户生成了多少特定事件。但是,在这两个列表中, .count 属性是相同的值。事实上,带注释的“计数”等于用户生成的事件数,无论类型如何。所以看起来我的具体
authusage = baseusage.exclude(loggedevent__authevent__id__lt=1)

不按子类排除。我尝试过 id__lt=1、id__isnull=True 等。哈尔普。

最佳答案

Django 模型继承的关键是记住,对于非抽象基类,所有东西实际上都是基类的一个实例,它可能碰巧有一些额外的数据从单独的表中捆绑在一边。这意味着当您在基表上进行搜索时,您将返回基类的实例,并且如果不对子类表进行重复的数据库查询以查看它们是否包含具有匹配键的记录,就无法判断它是哪个子类( “我有一个事件。它在 AuthEvent 中有记录吗?没有。LDAP 事件呢?...”)。除其他外,这意味着如果不对每个子类表进行连接,就无法在基类的普通查询中轻松过滤它们。

您有两种选择:一种是简单地对子类进行查询并计算结果(ldap_event_count = LDAPEvent.objects.filter(user=foo).count(),...),这对于单个报告可能就足够了。我通常建议向基类添加内容类型字段,这样您就可以有效地判断实例是哪个特定的子类,而无需进行其他查询:
content_type = models.ForeignKey("contenttypes.ContentType")
这允许两个主要改进:最常见的一个是您可以通用地处理许多事件,而无需执行诸如命中子类特定访问器(例如 event.autheventevent.ldapevent )和处理 DoesNotExist 之类的操作。 .在这种情况下,重写查询也很容易,因为您可以执行类似 Event.objects.aggregate(Count("content_type")) 的操作。获取报告值,如果您的逻辑变得更复杂(“事件是 Auth 或 LDAP 和……”),这将变得特别方便。

关于django - 在 Django 中对多表继承进行注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2837422/

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