2👍
The ContentTypeManager has some methods for getting a content type.
ContentType.objects.get_for_model(model_or_instance)
ContentType.objects.get_by_natural_key(app_label, model)
Both methods use the same internal cache for their results. So using them instead of filtering directly may avoid hitting the database.
However if you only need the content type as a subquery you should filter like:
(assuming your field name is ‘actor_content_type’)
Action.objects.filter(actor_content_type__app_label="auth",
actor_content_type__model="user", actor_object_id=request.user.id)
or
Action.objects.filter(actor_content=ContentType.objects.filter(app_label="auth",
model="user"), actor_object_id=request.user.id)
It is worth to mention that although there is a nested query in the latest snippet django converts this into a single sql statement.
If you are planing on using the actions actors, note that this will hit the database for every action in the query. You can avoid this by setting the actor manually.
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)
Additional notes:
- The actor_object_id should by an
PositiveIntegerField
. - Consider using
index_together = (('actor_content_type',
on your models meta class.
'actor_object_id'),)
👤kanu
Source:stackexchange.com