Django: Get current user in save model

I want the current user to log in (request.user) in the save method of models.py. I want to check the role of the user and perform some operations based on his role. I have cited the models.py code below.

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) 

Here the Tasks model is used as a built-in Schedule model. I want to check the role of the current registered user and update another model based on the user role. Here I need request.user to check the role of the current user. I do not use any forms or templates and fully use django admin. So, is there a way to get request.user in the save models of a method, or check and update values ​​in another model in admin.py.

I checked most of these issues in stackoverflow and none of them provided me with the perfect solution. So please provide me an answer to fix this. Thanks in advance.

+43
python django django-models
Jun 12 '12 at 6:22
source share
4 answers

You can solve this problem from a different angle. Instead of changing the method for saving models, you should override the AdminSites save_model method. There you will receive a request object and you will be able to access the registered user data, as you have already indicated.

Take a look at this chapter of the docs: Django ModelAdmin documentation save_model

Hope this helps you.

+31
Jun 12 2018-12-12T00:
source share
β€” -

I found a way to do this, but this is due to the MiddleWare declaration. Create a file called get_username.py inside your application with this content:

 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 

Edit your settings.py and add it to MIDDLEWARE_CLASSES :

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

Now, in your save() method, you can get the current username as follows:

 from get_username import get_username ... def save(self, *args, **kwargs): req = get_username() print "Your username is: %s" % (req.user) 
+18
Mar 31 '16 at 8:53
source share

I do not think the save_model override method is a better option. Suppose, for example, that you want to save user information or check the model based on user information, and that save () does not come from the view or the admin itself.

What people ask are constructs like those that:

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

or

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

The best approach I've found so far:

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

+8
Nov 03 '12 at 1:45
source share

The solution suggested by @nKn is a good starting point, but when I tried to implement it today, I ran into two problems:

  • In the current version of Django middleware, created as a simple object, it does not work.
  • Unittests fail (because they usually run on the same thread, so your request can be inserted between two consecutive tests if the first test has an HTTP request and the second does not).

Here is my updated middleware code that works with Django 1.10 and does not interrupt 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 
+7
Feb 27 '17 at 16:43 on
source share



All Articles