type queryset query example python django django-models

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:

  1. En la versión actual de Django, el middleware creado como objeto simple no funciona.
  2. 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:

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


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.