如何通过content_type ID获取用户

时间:2013-12-06 17:07:44

标签: python django django-contenttypes

我正在尝试使用使用泛型关系的django应用程序,而且我是内容类型的新手。 使用admin,我可以看到用户内容类型为14的对象

因此,我可以写一个视图

list = Action.objects.filter(actor_content_type=14)

这将生成与用户对象匹配的所有对象的列表

但是,如果我想要特定用户,例如request.user,我该如何过滤?我尝试了以下内容并失败了

list = Action.objects.filter(actor_content_type=request.user)

这是Action模型:

class Action(models.Model)
    user_content_type = models.ForeignKey(ContentType, related_name='actor')
    actor_object_id = models.CharField(max_length=255)
    actor = generic.GenericForeignKey('actor_content_type', 'actor_object_id')

1 个答案:

答案 0 :(得分:1)

ContentTypeManager有一些获取内容类型的方法。

ContentType.objects.get_for_model(model_or_instance)

ContentType.objects.get_by_natural_key(app_label, model)

两种方法都使用相同的内部缓存来获得结果。因此,使用它们而不是直接过滤可能会避免命中数据库。

但是,如果您只需要将内容类型作为子查询,则应该过滤: (假设您的字段名称是'actor_content_type')

Action.objects.filter(actor_content_type__app_label="auth",
        actor_content_type__model="user", actor_object_id=request.user.id)

Action.objects.filter(actor_content=ContentType.objects.filter(app_label="auth", 
        model="user"), actor_object_id=request.user.id)

值得一提的是,虽然最新的代码片段中有嵌套查询,但django会将其转换为单个sql语句。

如果您正在计划使用actions actor,请注意,这将针对查询中的每个操作访问数据库。您可以通过手动设置actor来避免这种情况。

user = request.user
actions = Action.objects.filter(
    actor_content_type__app_label="auth",
    actor_content_type__model="user", 
    actor_object_id=user.id)

actor_cache_key = Action.actor.cache_attr
for action in actions:
    setattr(action, actor_cache_key, user)

附加说明:

  • actor_object_id应该是PositiveIntegerField
  • 考虑在模型元类上使用index_together = (('actor_content_type', 'actor_object_id'),)