Какой простой способ украсить модели Django специфичными для запроса атрибутами? - PullRequest
4 голосов
/ 07 февраля 2010

Я сериализую Пользовательские объекты в JSON, и я хотел бы указать в ответе JSON, дружит ли сериализованный пользователь с пользователем, выполняющим запрос.

Я добавил метод to_dict () в мою модель User, которая выполняет предварительную обработку, необходимую для сериализации объекта, - это было бы хорошим местом для добавления атрибута, указывающего на дружбу, но поскольку User.to_dict () не У меня нет доступа к объекту запроса, я не могу сделать это там.

Сделать это в представлении легко, но я не хочу повторять этот код в других представлениях. Я бы хотел "обновить" объекты User до объектов User с поддержкой запроса.

Модель пользователя django.contrib.auth имеет атрибут is_authenticated, который на самом деле является атрибутом запроса, а не модели - этот атрибут имеет смысл только в контексте определенного веб-запроса.

Это как если бы я должен был заменить request.user экземпляром RequestUser, новым классом, который принимает User и Request и добавляет специфичные для запроса атрибуты. Какой чистый способ сделать это?

Ответы [ 2 ]

1 голос
/ 07 февраля 2010

Вы можете создать прокси-модель auth.User и добавить туда свой метод is_friend. http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-model-managers

Что касается метода is_authenticated, он немного проще, чем вы думаете. Обработчик контекста пользователя делает доступным специальный тип пользователей, если они не вошли в систему, то есть AnonymousUser. Этот класс всегда возвращает False при вызове is_authenticated. Аналогично, обычный класс User всегда возвращает True, когда вызывается is_authenticated.

Короче, не беспокойтесь об объекте запроса. Если текущий пользователь не вошел в систему, переменная пользователя, доступная в вашем представлении, будет использовать класс AnonymousUser и ваш метод is_friends не будет найден.

1 голос
/ 07 февраля 2010

Это на самом деле не отвечает на ваш вопрос, но вы уверены, что хотите справиться с дружбой с помощью метода на пользователя? Я говорю это, потому что:

  1. Логика, окружающая дружбу, предположительно в другом приложении, так что вы можете явно указать вызов функции, определенной в этом приложении;
  2. Дружба - это почти всегда симметричное отношение, поэтому использование метода для пользователя приводит к избыточности (a.is_friend_with(b) == b.is_friends_with(a)). Если позже вы захотите, например, кешировать результат вызова, имеет смысл определить функцию, которая просто принимает пользовательские объекты в качестве произвольно упорядоченных аргументов; и
  3. Вы, вероятно, не хотите делать что-то слишком причудливое с HttpRequest или User, поскольку это может запутать других разработчиков.

Мой подход состоял бы в том, чтобы определить метод менеджера в любой модели, представляющей дружбу, и явно передать в нее пользователей, например, так: Friendship.objects.are_friends(other_user, request.user).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...