当前位置: 首页 > 面试题库 >

Django自定义管理器-如何仅返回已登录用户创建的对象?

秋飞鸾
2023-03-14
问题内容

我想覆盖自定义对象模型管理器,以仅返回特定用户创建的对象。管理员用户仍应使用对象模型管理器返回所有对象。

现在,我找到了一种可行的方法。他们建议创建自己的中间件,如下所示:

#### myproject/middleware/threadlocals.py

try:
    from threading import local
except ImportError:
    # Python 2.3 compatibility
    from django.utils._threading_local import local

_thread_locals = local()

def get_current_user():
    return getattr(_thread_locals, 'user', None)

class ThreadLocals(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage."""
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)

#### end

在“自定义管理器”中,你可以调用该get_current_user()方法以仅返回特定用户创建的对象。

class UserContactManager(models.Manager):
    def get_query_set(self):
        return super(UserContactManager, self).get_query_set().filter(creator=get_current_user())

这是用例的好方法吗?这样行吗?还是像“用大锤砸破螺母”?;-)

只需使用:

Contact.objects.filter(created_by= user)

在每个视图中,对我来说看起来都不是很整洁。

编辑不要使用这种中间件方法!
使用下面的Jack M.
经过一段时间的测试,这种方法的行为非常奇怪,并且使用这种方法,你将全局状态与当前请求混合在一起。

使用下面介绍的方法。这真的很容易,不需要使用中间件。

在模型中创建一个自定义管理器,该函数具有将当前用户或任何其他用户作为输入的功能。

#in your models.py
class HourRecordManager(models.Manager):
    def for_user(self, user):
        return self.get_query_set().filter(created_by=user)

class HourRecord(models.Model):
    #Managers
    objects = HourRecordManager()

#in vour view you can call the manager like this and get returned only the objects from the currently logged-in user.

hr_set = HourRecord.objects.for_user(request.user)

问题答案:

解决此问题的一种方法是创建一个新方法,而不是重新定义get_query_set。类似于以下内容:

class UserContactManager(models.Manager):
    def for_user(self, user):
        return super(UserContactManager, self).get_query_set().filter(creator=user)

class UserContact(models.Model):
    [...]
    objects = UserContactManager()

这使你的视图看起来像这样:

contacts = Contact.objects.for_user(request.user)

这应该有助于使视图保持简单,并且因为你将使用Django的内置功能,所以将来不太可能中断。



 类似资料:
  • 问题内容: 我在Django中启用了用户身份验证模块,但是当我使用它时,它仅询问用户名和两个密码/密码确认字段。我还希望将电子邮件和全名字段全部设置为必填字段。 我已经做到了: 现在,该表单显示了新字段,但是没有将它们保存到数据库中。 我怎样才能解决这个问题? 问题答案: 用户模型中没有调用此字段。 如果要使用原始模型存储名称,则必须将其分别存储为名字和姓氏。 编辑: 如果您只希望表单中的一个字段

  • 问题内容: 我想知道如何在opencart中创建自定义管理面板页面。 需要使用控制器登录- 管理面板似乎没有使用与普通站点相同的控制器。我知道如何使用opencart制作自定义页面(但这不适用于管理员) 一个简单的Hello World示例将是很棒的 问题答案: 路径名称在OpenCart 2中已更改-您将要创建 然后路线变成 OpenCart 1.x 包括完整的MVC流。 我发现了如何做到这一点

  • 在Spring Security中使用自定义JSP登录页面相当容易。不过,我们的应用程序是基于Vaadin的,我不想使用JSP登录页面。我想要的是作为Vaadin小部件创建的自定义高级登录窗口。 从技术上讲,我可以使用Vaadin的FormLayout和名称字段,比如j_用户名和j_密码……但这是Java类,而不是JSP文件,那么我在http Spring Security元素中指定了什么?我的意

  • 问题内容: 扩展Django的默认用户 如果你对Django的用户模型完全满意,并且只想添加一些其他配置文件信息,则可以简单地子类化并添加自定义配置文件字段。此类提供默认用户的完整实现,作为抽象模型。。我创建了一个新模型,如下所示: 这在admin中几乎像Django的standard一样显示。但是,admin中最重要的区别是不存在password-(re)set字段,而是显示了普通的CharFi

  • 问题内容: 我在这里问了有关最新的Spring框架和基于代码的配置的问题 initializer MVC config security config security initializer custom login 但是,现在我有关于自定义登录的新问题。 发布到j_spring_security_check时,我会收到http 302。 我正在请求/,但登录后仍保留在登录页面上。 因为我使用的

  • 用户,与猫一样,常常觉得有必要标记他们的领地。 与猫不同,用户往往要定制自己的 shell 环境,如终端显示的颜色、别名等。 这通常是通过用户家目录下的一些以点开始的环境文件实现的,例如:.bash_profile。 通过修改上一节的 user::virtual::ssh_user 类,你可以将环境文件添加到基于 Puppet 的用户管理中。 在这个类中,你可以有选择地为客户提供 Puppet 文