开发者

What's a clean way to adorn Django models with request-specific attributes?

I'm serializing User objects to JSON, and I'd like to indicate in the JSON response whether the serialized user is friends with the user making the request.

I've added a to_dict() method to my User model that does the pre-processing necessary to serialize the object--that would be a nice place to add an attribute indicating friendship, but since User.to_dict() doesn't have access to the request object, I can't seem to do it there.

Doing it in a view is easy, but I don't want t开发者_开发百科o repeat that code in other views. I'd like to "upgrade" User objects to request-aware User objects.

The django.contrib.auth User model has an is_authenticated attribute, which is really an attribute of the request and not of the model--that attribute only makes sense within the context of a particular web request.

It's as if I should replace request.user with an instance of RequestUser, a new class that takes a User and a Request and adds request-specific attributes. What's a clean way to do that?


This doesn't really answer your question, but are you sure you want to handle friendship through a method on User? I say this because:

  1. The logic surrounding friendship is presumably in another app, so you might want to be explicit about calling a function defined in that app;
  2. Friendship is almost always a symmetric relation, so using a method on User leads to redundancy (a.is_friend_with(b) == b.is_friends_with(a)). If you later want to cache the result of the call, for instance, it makes sense to define a function which simply accepts user objects as arbitrarily ordered arguments; and,
  3. You probably don't want to do anything too fancy with HttpRequest or User as it's likely to confuse other developers.

My approach would be to define a manager method on whatever model represents friendship, and explicitly pass in users to that, like so: Friendship.objects.are_friends(other_user, request.user).


You could create a proxy model of auth.User and add your is_friend method there. http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-model-managers

As for the is_authenticated method, its a little simpler than you may think. The user context processor makes a special type of user available if they are not logged in, that is the AnonymousUser. This class always returns False when is_authenticated is called. Likewise the regular User class always returns True when is_authenticated is called.

In short, don't worry about the request object. If the current user is not logged in, the user variable available in your view will be using the AnonymousUser class and your is_friends method will not be found.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜