Administradores personalizados de Django: ¿cómo devuelvo solo los objetos creados por el usuario que inició sesión?

Quiero sobrescribir el administrador de modelos de objetos personalizados para que solo devuelva objetos creados por un usuario específico. Los usuarios administradores aún deben devolver todos los objetos utilizando el administrador de modelos de objetos.

Ahora he encontrado un enfoque que podría funcionar. Se proponen crear su propio middleware con el siguiente aspecto:

#### 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 

Y en el Administrador personalizado, puede llamar al método get_current_user() para devolver solo los objetos creados por un usuario específico.

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

¿Es este un buen enfoque para este caso de uso? esto funcionara? ¿O es como “usar un mazo para romper una nuez”? 😉

Solo usando:

 Contact.objects.filter(created_by= user) 

en cada vista no se ve muy limpio para mí.

EDITAR ¡No use este enfoque de middleware!

utilizar el enfoque establecido por Jack M. a continuación

Después de un tiempo de prueba, este enfoque se comportó bastante extraño y con este enfoque se mezcla un estado global con una solicitud actual.

Use el enfoque presentado a continuación. Es realmente fácil y no hay necesidad de hackear con el middleware.

cree un administrador personalizado en su modelo con una función que espera que el usuario actual o cualquier otro usuario lo haga.

 #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) 

Ver también esta discusión sobre el enfoque middelware.

Una forma de manejar esto sería crear un nuevo método en lugar de redefinir get_query_set . Algo como:

 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() 

Esto permite que su vista se vea así:

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

Esto debería ayudar a mantener su vista simple, y debido a que usaría las características integradas de Django, no es probable que se rompa en el futuro.

Parece necesario usar el middleware para almacenar la información del usuario.

Sin embargo, prefiero no modificar los objects predeterminados de ModelManager , sino conectarlo a un administrador diferente, que user_objects en el código, por ejemplo, en su caso user_objects lugar de objetos.

Como usará esto solo en vistas que son @login_required , no necesita todo el manejo complejo de errores en Middleware.

Solo mi 2 ¢.

Gracias por compartir el código Solución no tan buena en cuanto a la capacidad de prueba, pero no encontré otra forma de personalizar los gestores de modelos mediante la solicitud de datos de objetos. Sería mejor tener control sobre la creación del administrador, pero Django no lo permite.

O incluso más simple y use la clave foránea para recuperar el conjunto de preguntas.

Si tienes un modelo así

 class HourRecord(models.Model): created_by = ForeignKey(get_user_model(), related_name='hour_records') 

Puede consultar HourRecords en una vista por usuario con simplemente:

 request.user.hour_records.all()