如何代表另一个用户保存记录和获取记录
How to save records and get records on behalf of another user
我正在开发一个 Django 1.5 项目。
该应用程序包含
的用户层次结构
Owner
Admin
Viewer
- Owner owns all the data in the database.
- Admin users are created by the owner and have different login credentials. Can add/edit/delete data under Owner.
- Viewer users are created by the owner and have different login credentials. Can view data created under the Owner.
Users 模型有一个字段 is_shared
(布尔值)来标识主要用户和共享用户,并且 access_level
映射到另一个模型 多用户.
我想到了实现方式
- 更新所有视图集并检查
get_queryset
。
- 如果用户有
is_shared=True
,将在何处进行首次检查
- 然后签入 MultiUser 模型,
- 从 MultiUser 获取
user
然后代表用户过滤记录。
但这需要更改整个应用程序视图集。
有没有办法在不更改整个应用程序的情况下执行此操作。
可能是 middleware
.
Edit 2: MultiUser model
class MultiUser(models.Model):
user = models.ForeignKey(User, related_name='owner_user')
shared_user = models.ForeignKey(User, related_name='shared_user')
access_level = models.CharField(max_length=50)
您可以使用单个基 class 来处理,而不是更新所有视图集。
from django.http import HttpResponse
from django.views import View
class BaseView(View):
def get_queryset(self, request):
if request.user.is_shared:
#some is_shared value
u = MultiUser.objects.filter(user=request.user)
if u.exists():
return #some multiuser value
else:
return #some non multi user value
class Meta:
abstract=True
class MyView(BaseView):
def get(self, request):
q = self.get_queryset
#view logic
return HttpResponse('result')
class MyView2(BaseView):
def get(self, request):
q = self.get_queryset
#view logic
return HttpResponse('result')
我通过创建一个包含内容
的中间件解决了这个问题
class MultiUserMiddleware(object):
def process_request(self, request):
"""
Check if user profile is is_shared=True
If user is a shared user, get owner user from multi user
and assign owner user to request.user
Any multi user profile created by the owner user will work on behalf of the owner user
"""
user = request.user
if not user.is_anonymous():
# if request.path in settings.MUTLIUSER_ALLOWED_PATH:
# return None
# Search using wildcard
if any(fnmatch(request.path, p) for p in settings.MUTLIUSER_ALLOWED_PATH):
return None
try:
if user.profile.get().is_shared:
owner = MultiUser.objects.filter(shared_user=user)[0].user
request.user = owner
except:
return None
return None
此中间件根据 is_shared
检查用户帐户是否为共享用户,然后将 request.user 更改为拥有者用户对象。这也可以防止更改 settings 文件(例如,配置文件、change_password 等)中定义的特定路径的请求所有者。
我正在开发一个 Django 1.5 项目。
该应用程序包含
的用户层次结构Owner
Admin
Viewer
- Owner owns all the data in the database.
- Admin users are created by the owner and have different login credentials. Can add/edit/delete data under Owner.
- Viewer users are created by the owner and have different login credentials. Can view data created under the Owner.
Users 模型有一个字段 is_shared
(布尔值)来标识主要用户和共享用户,并且 access_level
映射到另一个模型 多用户.
我想到了实现方式
- 更新所有视图集并检查
get_queryset
。 - 如果用户有
is_shared=True
,将在何处进行首次检查
- 然后签入 MultiUser 模型,
- 从 MultiUser 获取
user
然后代表用户过滤记录。
但这需要更改整个应用程序视图集。
有没有办法在不更改整个应用程序的情况下执行此操作。
可能是 middleware
.
Edit 2: MultiUser model
class MultiUser(models.Model):
user = models.ForeignKey(User, related_name='owner_user')
shared_user = models.ForeignKey(User, related_name='shared_user')
access_level = models.CharField(max_length=50)
您可以使用单个基 class 来处理,而不是更新所有视图集。
from django.http import HttpResponse
from django.views import View
class BaseView(View):
def get_queryset(self, request):
if request.user.is_shared:
#some is_shared value
u = MultiUser.objects.filter(user=request.user)
if u.exists():
return #some multiuser value
else:
return #some non multi user value
class Meta:
abstract=True
class MyView(BaseView):
def get(self, request):
q = self.get_queryset
#view logic
return HttpResponse('result')
class MyView2(BaseView):
def get(self, request):
q = self.get_queryset
#view logic
return HttpResponse('result')
我通过创建一个包含内容
的中间件解决了这个问题class MultiUserMiddleware(object):
def process_request(self, request):
"""
Check if user profile is is_shared=True
If user is a shared user, get owner user from multi user
and assign owner user to request.user
Any multi user profile created by the owner user will work on behalf of the owner user
"""
user = request.user
if not user.is_anonymous():
# if request.path in settings.MUTLIUSER_ALLOWED_PATH:
# return None
# Search using wildcard
if any(fnmatch(request.path, p) for p in settings.MUTLIUSER_ALLOWED_PATH):
return None
try:
if user.profile.get().is_shared:
owner = MultiUser.objects.filter(shared_user=user)[0].user
request.user = owner
except:
return None
return None
此中间件根据 is_shared
检查用户帐户是否为共享用户,然后将 request.user 更改为拥有者用户对象。这也可以防止更改 settings 文件(例如,配置文件、change_password 等)中定义的特定路径的请求所有者。