Django - 用户子类的替代方案?

0 投票
1 回答
853 浏览
提问于 2025-04-15 12:24

我正在使用Django自带的标准用户模型(django.contrib.auth)。在我的Django应用中,我创建了一些自己的模型,并建立了它们之间的关系,像这样:

from django.db import models
from django.contrib.auth.models import User

class GroupMembership(models.Model):
    user = models.ForeignKey(User, null = True, blank = True, related_name='memberships')
    #other irrelevant fields removed from example

现在我可以这样做,获取某个用户当前的所有会员信息:

user.memberships.all()

不过,我想进行一个更复杂的查询,比如这样:

user.memberships.all().select_related('group__name')

这个查询可以正常工作,但我想在模板中获取这些数据。把这种逻辑放在模板里感觉很傻(而且我似乎也无法让它正常工作),所以我想找一个更好的方法来处理这个问题。我可以通过子类化User来实现,但这似乎不是个好主意——将来我可能想把我的应用移到其他Django网站上,如果有其他应用也子类化了User,那我就无法让它正常工作了。

最好的办法是在GroupMembership里创建一个叫get_by_user(user)的方法吗?我能在模板中调用这个方法吗?

如果有人能给我一些关于如何构建这个的建议,我会非常感激——抱歉如果这段话有点长或模糊。

1 个回答

3

首先,调用 select_related 并传递参数,其实并不会立刻做什么。这只是一个提示,告诉系统应该准备好缓存。

你绝对不会在模板里调用 select_related,只会在视图函数里使用。而且只有在你确定需要那些相关对象来进行其他处理时,才会用到它。

“在 GroupMembership 里创建一个叫做 get_by_user(user) 的方法,这样做是否最好?”

你已经有这个方法了。我不太确定它有什么问题。

 GroupMembership.objects.filter( user="someUser" )

“我能在模板里调用这个吗?”

不行。这就是视图函数的作用。

 groups = GroupMembership.objects.filter( user="someUser" )

然后你把 groups 对象提供给模板进行渲染。


编辑

这只是一行代码;在所有视图函数里加上这一行代码并不算太麻烦。

如果你想让这个在每个页面上都出现,你有很多选择,不需要重复这一行代码。

  1. 一个视图函数可以调用另一个函数。

  2. 你可以尝试使用可调用对象,而不是简单的函数;这些可调用对象可以继承一个通用的可调用对象,来填充这些信息。

  3. 你可以添加一个模板上下文处理器,把这些信息放入所有渲染的模板的上下文中。

  4. 你可以写一个自己的装饰器,确保在每个使用这个装饰器的视图函数中都执行这个操作。

撰写回答