【问题标题】:How to save records and get records on behalf of another user如何代表其他用户保存记录和获取记录
【发布时间】:2019-07-05 17:41:01
【问题描述】:

我正在开发一个 Django 1.5 项目。

应用程序包含的用户层次结构

Owner
Admin
Viewer
  • 所有者拥有数据库中的所有数据。
  • 管理员用户由所有者创建并具有不同的登录凭据。可以在 Owner 下添加/编辑/删除数据。
  • 查看者用户由所有者创建并具有不同的登录凭据。可以查看 Owner 下创建的数据。

Users 模型有一个字段 is_shared(布尔值)来识别主要用户和共享用户,access_level 映射到另一个模型 MultiUser

我已经想过以这种方式实现它

  1. 更新所有视图集并签入get_queryset
  2. 如果用户有is_shared=True,将在哪里进行第一次检查
  3. 然后签入MultiUser模型,
  4. MultiUser获取user,然后代表用户过滤记录。

但这需要对整个应用程序视图集进行更改。

有没有办法在不更改整个应用程序的情况下做到这一点。 可能是middleware

编辑 2:多用户模型

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)

【问题讨论】:

  • 如果您还提供视图集和 MultUser 模型的代码,将会很有帮助。
  • 我也很困惑。 viewsets 是 django-rest-framework 的一部分,而不是 django。纠正我吗?
  • viewsetsDRF 的一部分
  • 添加了MultiUser 模型。视图集不具体,已经有很多视图集了。

标签: django django-1.5


【解决方案1】:

您可以使用单个基类来处理,而不是更新所有视图集。

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

【讨论】:

  • 有很多视图正在扩展其他自定义视图或通用 DRF 视图。您的解决方案将需要更新所有视图集以扩展 BaseView
  • “有很多视图正在扩展其他自定义视图”。您可能有一些冗余代码。请在此处登录并分享您的views.pygist.github.com 我会提供帮助。
【解决方案2】:

我通过创建一个包含内容的中间件解决了这个问题

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 等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    相关资源
    最近更新 更多