queryset - models py python
Django: obtener usuario actual en el modelo de guardar (4)
Deseo obtener el usuario registrado actualmente (request.user) en el método save de models.py. Quiero verificar el rol del usuario y realizar algunas operaciones en función de su rol. He dado el código de models.py a continuación.
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)
Aquí el modelo de tareas se está utilizando como en línea en el modelo de parte de horas . Quiero verificar el rol del usuario registrado actual y actualizar otro modelo en función del rol del usuario. Aquí necesito request.user para verificar el rol del usuario actual. No estoy usando formularios o plantillas y uso completamente el administrador de django. Entonces, ¿hay algún método para obtener request.user en el método de guardar modelos o para verificar y actualizar los valores en otro modelo en admin.py?
He comprobado la mayoría de las preguntas similares en stackoverflow y ninguna de ellas me proporciona una solución perfecta. Así que por favor dame una respuesta para arreglar esto. Gracias por adelantado.
Encontré una manera de hacerlo, implica declarar MiddleWare, sin embargo. Crea un archivo llamado get_username.py
dentro de tu aplicación, con este contenido:
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
Edite su settings.py
y agréguelo a MIDDLEWARE_CLASSES
:
MIDDLEWARE_CLASSES = (
...
''yourapp.get_username.RequestMiddleware'',
)
Ahora, en su método save()
, puede obtener el nombre de usuario actual de esta manera:
from get_username import get_username
...
def save(self, *args, **kwargs):
req = get_username()
print "Your username is: %s" % (req.user)
La solución propuesta por @nKn es un buen punto de partida, pero cuando traté de implementarla hoy, me enfrenté a dos problemas:
- En la versión actual de Django, el middleware creado como objeto simple no funciona.
- Los unittest están fallando (ya que generalmente se ejecutan en un solo subproceso, por lo que su ''solicitud'' se puede pegar entre dos pruebas consecutivas si la primera prueba tiene una solicitud HTTP y la segunda no).
Aquí está mi código de middleware actualizado, que funciona con Django 1.10 y no rompe 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)
No creo que la anulación del método save_model sea la mejor opción. Imagine, por ejemplo, que desea guardar la información del usuario o validar el modelo en función de la información del usuario y que save () no proviene de una vista o del sitio de administración en sí.
Lo que la gente está pidiendo son construcciones como esas:
def save(..)
self.user = current_user()
o
def save(..)
user = current_user()
if user.group == ''XPTO'':
error(''This user cannot edit this record'')
El mejor enfoque que encontré hasta ahora es:
Puedes abordar este problema desde otro ángulo. En lugar de cambiar el método de guardar modelos, debe anular el método AdminSites save_model
. Allí tendrá el objeto de solicitud y puede acceder a los datos del usuario registrado como ya ha señalado.
Eche un vistazo a este capítulo de los documentos: documentación de Django ModelAdmin save_model
Espero que te haya ayudado.