Django:在模型保存中获取当前用户

我想在models.py的保存方法中获取当前login的用户(request.user)。 我想检查用户的angular色,并根据他的angular色执行一些操作。 我已经给出下面的models.py代码。

models.py

class TimeSheet(models.Model): check_in_time = models.TimeField() check_out_time = models.TimeField() class Tasks(models.Model): time_sheet = models.ForeignKey(TimeSheet) project = models.ForeignKey(Project) start_time = models.TimeField() end_time = models.TimeField() def save(self, *args, **kwargs): project = SpentTime.objects.get(project__project__id = self.project.id) start = datetime.datetime.strptime(str(self.start_time), '%H:%M:%S') end = datetime.datetime.strptime(str(self.end_time), '%H:%M:%S') time = float("{0:.2f}".format((end - start).seconds/3600.0)) if common.isDesigner(request.user): SpentTime.objects.filter(project__project__id = self.project.id).update(design = float(project.design) + time) if common.isDeveloper(request.user): SpentTime.objects.filter(project__project__id = self.project.id).update(develop = float(project.develop) + time) super(Tasks, self).save(*args, **kwargs) 

这里Tasks模型在Timesheet模型中被内联使用。 我想检查当前login用户的angular色,并根据用户的angular色更新另一个模型。 这里我需要request.user来检查当前用户的angular色。 我没有使用任何forms或模板,并完全利用Django的pipe理。 那么是否有任何方法可以在模型保存方法中获取request.user ,或者在admin.py中检查和更新另一个模型中的值。

我已经检查了大多数类似的问题在stackoverflow中,没有一个给我提供了一个完美的解决scheme。 所以请给我一个解决这个问题的答案。 提前致谢。

你可以从另一个angular度来解决这个问题。 您应该重写AdminSites save_model方法,而不是更改模型save方法。 在那里您将拥有请求对象,并可以像您已经指出的那样访问login的用户数据。

看看这个文档的这一章: Django ModelAdmin文档save_model

希望能帮到你。

我find了一个方法来做到这一点,但是它涉及到声明一个MiddleWare。 在你的应用程序中创build一个名为get_username.py的文件,内容如下:

 from threading import current_thread _requests = {} def get_username(): t = current_thread() if t not in _requests: return None return _requests[t] class RequestMiddleware(object): def process_request(self, request): _requests[current_thread()] = request 

编辑您的settings.py并将其添加到MIDDLEWARE_CLASSES

 MIDDLEWARE_CLASSES = ( ... 'yourapp.get_username.RequestMiddleware', ) 

现在,在你的save()方法中,你可以得到像这样的当前用户名:

 from get_username import get_username ... def save(self, *args, **kwargs): req = get_username() print "Your username is: %s" % (req.user) 

我不认为save_model方法覆盖是最好的select。 想象一下,例如,想要保存用户信息或根据用户信息validation模型,并且save()不是来自视图或pipe理站点本身。

人们所要求的是这样的build筑:

 def save(..) self.user = current_user() 

要么

 def save(..) user = current_user() if user.group == 'XPTO': error('This user cannot edit this record') 

目前为止我发现的最好的方法是:

https://bitbucket.org/q/django-current-user/overview

@nKn提出的解决scheme是一个很好的起点,但是当我今天试图实现时,我遇到了两个问题:

  1. 在当前的Django版本中,创build为普通对象的中间件不起作用。
  2. unit testing失败(因为它们通常运行在单线程中,所以如果第一个testing有HTTP请求,而第二个testing没有),那么你的'请求'将会被粘在两个后续testing之间。

这里是我更新的中间件代码,它与Django 1.10一起工作,不会破坏unittests:

 from threading import current_thread from django.utils.deprecation import MiddlewareMixin _requests = {} def current_request(): return _requests.get(current_thread().ident, None) class RequestMiddleware(MiddlewareMixin): def process_request(self, request): _requests[current_thread().ident] = request def process_response(self, request, response): # when response is ready, request should be flushed _requests.pop(current_thread().ident, None) return response def process_exception(self, request, exception): # if an exception has happened, request should be flushed too _requests.pop(current_thread().ident, None) raise exception