根据您是否准备好更改“用例”,您的问题可能有几个答案:
a)您不能更改用例:这是不可能的,因为一个 Django 会话绑定到一个浏览器会话,无论是多个浏览器窗口实例还是选项卡。
b)您可以更改用例:用户仍然可以使用多个浏览器(或配置文件(或 chrome/chromium 中的隐私浏览模式))来实现此目的,而无需对您的代码进行任何修改。
c)您可以在您的网站中实现“用户”切换功能,允许用户在不同窗口的同一会话中拥有多个活动配置文件,其目的类似于 github 组织切换功能或 facebook 页面/组织切换但你可以在多个选项卡中拥有多个用户的个人资料,这在 github 或 facebook 上并非如此。
要实现c)您需要将“SubProfile”模型实例附加到您的“用户”模型,并根据查询字符串参数在每个传入请求上激活正确的子配置文件,并在请求之间保留子配置文件信息。
1)我猜你已经有Subprofile
一个带有外键的模型django.contrib.auth.models.User
,你可能还有一个允许用户更改其子配置文件的视图。为了使子配置文件切换工作,它需要在当前选项卡会话中保留它正在使用的子配置文件中的信息,因为它需要在查询字符串中添加一个参数,因为它是绑定选项卡而不是用户的唯一位置-会议。例如“子配置文件=123”。您需要使用表单等正确验证子配置文件,视图如下所示:
def select_subprofile(request):
if request.method == 'POST':
form = SubProfileSelectForm(request)
if form.is_valid():
subprofile = form.cleaned_data['subprofile']
url = '%s?subprofile' % (reverse('homepage'), subprofile)
return redirect(url) # the redirect is something like '/homepage?subprofile=123'
else:
form = SubProfileSelectForm()
return render(request, 'myapp/subprofile_select.html', {'form':form})
这个视图可以是每个游戏的第一页。
2)之后,您需要为当前选项卡检索用户的子配置文件。为此,我们将在中间件中使用查询字符串(如果您不知道它是什么,请查找SO和与 Django 捆绑的示例中间件SubProfile
)可用于将当前实例附加到request.user
. 中间件将为每个传入请求附加与在查询字符串中找到的当前子配置文件信息对应的 SubProfile 实例到当前用户对象,中间件如下所示:
class SubProfileMiddleware(object):
def process_request(self, request):
subprofile = request.GET.get('subprofile', None)
if subprofile:
# it's important to check for user here or malicious users will be
# able to use Subprofiles of other users
subprofile = Subprofile.objects.filter(user=request.user, id=subprofile)
# This can also be written
# subprofile = request.user.subprofile_set.filter(id=subprofile)
if not subprofile:
# this is a malicious user
raise Http403
else:
request.user.subprofile = subprofile
else:
# set default subprofile
request.user.subprofile = self.user.default_subprofile
这样,您可以在应用程序的每个视图SubProfile
中subprofile
访问request.user
. 如果存在有效的查询字符串subprofile=123
,用户将激活这些子配置文件,如果没有,则为默认子配置文件。
假设您的应用程序是具有Organization
模型的应用程序,其中每个实例都有墙,用户可以使用子配置文件在其上发布消息,在墙上发布消息的功能具有以下签名post_on_organization_wall(subprofile, message, organization)
,使用此功能的视图将如下所示:
def organization_wall_post(request, organization):
organization = Organization.objects.get_object_or_404(organization)
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
post_on_organization_wall(request.user.subprofile, message, organisation)
else:
form = MessageForm()
return render(request, 'organisation/wall_post.html', {'form': form})
3)现在您需要跨请求保留子配置文件信息。最简单的方法是将每个调用替换{% url %}
为您自己的url
模板标签,该标签检查请求查询字符串是否存在子配置文件键并将其添加到请求的 url。您可以重用Django 的 url 模板标签的代码。