使用Django Queryset检查表中的ID

时间:2011-12-15 16:53:21

标签: python django django-models

我目前正在尝试计算用户活动,但只会在首次注册后两天计算。由于我将对数据进行后处理,我想让它返回一个Django QuerySet。

唯一相关的字段如下:

User
user_id, install_time

Activity
user_id, date, [list of activities]

虽然我已经将解决​​方案混合在一起,但效率非常低(O(n²)),因为我必须在连续的user_id循环中单独匹配for

目前,ForeignKey字段不适合我的模型。我找到了this;但是,我找不到只返回user_id匹配的date > install_time + datetime.timedelta(2)class User(models.Model): user_id = models.CharField(max_length=36) install_time = models.DateTimeField() class Activity(models.Model): user_id = models.CharField(max_length=36) date = models.DateTimeField() # Misc activity-related fields 的查询集的方法。

有什么想法吗?

编辑:这是我的模特:

{{1}}

2 个答案:

答案 0 :(得分:2)

如果没有看到你的模型,就不可能给你任何明确的方向,但是Django的查询API支持遍历模式。

您可能会执行以下操作:

from django.db.models import F

Activity.objects.filter(date__gt=F('user__install_time')+timedelta(2))

更新(基于修改)

设置模型的方式效率低下,不允许您利用上述代码。特别是,您应该在User上拥有Activity的外键。

class Activity(models.Model):
    user = models.ForeignKey(User)
    date = models.DateTimeField()
    ...

user_id上使用User可能也不是最佳选择。即使您没有直接指定它(或者我认为因为您没有直接指定它),Django会自动向您的模型添加id字段,该字段是主键。你的桌子。所以你的模型实际上是

 class User(models.Model):
     id = models.AutoField()
     user_id = models.CharField(max_length=36)
     install_time = models.DateTimeField()

在您的模型上同时使用iduser_id令人困惑。如果user_id与用户名相似,则将其重命名为username。否则,你可能根本不需要它。

最后,奇怪的是你实际上首先定义了一个User类。如果您打算使用Django的auth包进行身份验证和用户管理,那么您将遇到巨大的问题(这意味着您永远不会真正定义您的永远拥有User,以防万一)。如果您需要向内置User添加额外字段,则可以使用配置文件模型执行此操作。请参阅:https://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

答案 1 :(得分:2)

由于您的模型没有使用显式连接,因此您不能像Chris Pratt建议的那样使用字段F对象。

如果您无法修改架构,我可以看到另外两个仍然利用某些django ORM的选项,但是需要您编写SQL查询/片段。

我假设postgresql并且完全猜测django可能来自您所说的模型中的django没有正确命名。

QuerySet.extra E.g:

activity_set = Activity.objects.extra(
  tables=['myapp_user'],
  where=[
    "myapp_activity.user_id=myapp_user.user_id",
    "myapp_activity.date - myapp_user.install_time > '2 days'"
    ])

使用extra可能很尴尬,您可以通过str(activity_set.query)检查它生成的sql。

或者,您可以使用Manager.raw并完全手工制作查询。 E.g:

activity_set = Activity.objects.raw("""
 SELECT
   myapp_activity.* from myapp_activity, myapp_user
 WHERE 
   myapp_activity.user_id=myapp_user.user_id
   and myapp_activity.date - myapp_user.install_time > '2 days'
""")