What a clean way to decorate Django models with query-specific attributes?

I am serializing User objects in JSON, and I would like to indicate in the JSON response whether the serialized user is familiar with the user making the request.

I added the to_dict () method to my User model, which does the preprocessing necessary to serialize the object - this 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 not do it.

Doing this in a view is easy, but I don't want to repeat this code in other views. I would like to β€œupdate” User objects for User-user-aware objects.

The user model django.contrib.auth has an is_authenticated attribute, which is really a request attribute, not a model - this attribute only makes sense in the context of a specific web request.

As if I should replace request.user with an instance of RequestUser, a new class that accepts the user and the request and adds request-specific attributes. What a clean way to do this?

+4
source share
2 answers

This does not actually answer your question, but are you sure you want to make friendships through the user method? I say this because:

  • The logic surrounding friendship is presumably in another application, so you can be explicit about calling a function defined in this application;
  • Friendship is almost always a symmetric relation, so using the method for the 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 example, it makes sense to define a function that simply accepts user objects as arbitrarily ordered arguments; and,
  • You probably don't want to do anything with the HttpRequest or the user, as this may confuse other developers.

My approach would be to define a manager method for any model representing friendship, and explicitly pass this to users like this: Friendship.objects.are_friends(other_user, request.user) .

+1
source

You can create an auth.User proxy model and add the 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 easier than you think. The user context processor makes a particular type of user available if he is not logged in, that is, an anonymous user. This class always returns False when is_authenticated is called. Similarly, a 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 use the AnonymousUser class and your is_friends method will not be found.

+1
source

Source: https://habr.com/ru/post/1300527/


All Articles