用特定于请求的属性装饰 Django 模型的干净方法是什么?

发布于 2024-08-20 08:04:16 字数 448 浏览 6 评论 0原文

我正在将 User 对象序列化为 JSON,并且我想在 JSON 响应中指示序列化的用户是否与发出请求的用户是好友。

我在我的 User 模型中添加了一个 to_dict() 方法,该方法执行序列化对象所需的预处理——这将是添加指示友谊的属性的好地方,但由于 User.to_dict() 没有访问请求对象,我似乎无法在那里做到这一点。

在视图中执行此操作很容易,但我不想在其他视图中重复该代码。我想将用户对象“升级”为请求感知的用户对象。

django.contrib.auth 用户模型有一个 is_authenticated 属性,它实际上是请求的属性,而不是模型的属性 - 该属性仅在特定 Web 请求的上下文中才有意义。

就好像我应该用 RequestUser 的实例替换 request.user,这是一个接受 User 和 Request 并添加特定于请求的属性的新类。有什么干净的方法可以做到这一点?

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 to 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小鸟爱天空丶 2024-08-27 08:04:16

这并不能真正回答您的问题,但是您确定要通过 User 上的方法来处理友谊吗?我这样说是因为:

  1. 围绕友谊的逻辑可能在另一个应用程序中,因此您可能需要明确调用该应用程序中定义的函数;
  2. 友谊几乎总是对称关系,因此在 User 上使用方法会导致冗余(a.is_friend_with(b) == b.is_friends_with(a))。例如,如果您稍后想要缓存调用的结果,则定义一个仅接受用户对象作为任意排序参数的函数是有意义的;并且,
  3. 您可能不想对 HttpRequest 或 User 做任何过于花哨的事情,因为这可能会让其他开发人员感到困惑。

我的方法是在代表友谊的任何模型上定义一个管理器方法,并显式地将用户传递给该方法,如下所示:Friendship.objects.are_friends(other_user, request.user)

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).

别把无礼当个性 2024-08-27 08:04:16

您可以创建 auth.User 的代理模型并在其中添加 is_friend 方法。 http://docs.djangoproject.com/en /dev/topics/db/models/#proxy-model-managers

至于 is_authenticated 方法,它比你想象的要简单一些。用户上下文处理器使一种特殊类型的用户在未登录时可用,即 AnonymousUser。调用 is_authenticated 时,此类始终返回 False。同样,当调用 is_authenticated 时,常规 User 类始终返回 True。

简而言之,不用担心请求对象。如果当前用户未登录,则视图中可用的用户变量将使用 AnonymousUser 类,并且将找不到您的 is_friends 方法。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文