2013-12-06 8 views
0

Я пытаюсь использовать приложение django, которое использует общие отношения, и я новичок в типах контента. Использования администратора, я могу видеть объект, тип контента пользователя 14Как получить пользователя по content_type ID

Поэтому я могу написать в представлении

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

И это создает список всех объектов, которые соответствуют объекту пользователя

Однако, если я хочу, чтобы конкретный пользователь, например request.user, мог ли я фильтровать для этого? Я попробовал следующее и не

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

Вот Действие модель:

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') 
+0

Я смущен. Почему у пользователя есть тип контента? Типы контента относятся только к моделям, а не к экземплярам. –

+0

Ак, я тоже смущен, я как раз собирался отредактировать этот вопрос, когда сам обнаружил это. Теперь я понятия не имею, как объект действия хранит пользователей – bcoop713

ответ

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-запрос.

Если вы планируете использовать действия актеров, обратите внимание, что это приведет к попаданию в базу данных для каждого действия в запросе. Вы можете избежать этого, установив актера вручную.

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'),) в категориях моделей meta.
Смежные вопросы