2011-05-10 8 views
8

Para mi sitio web, casi todas las páginas tienen una barra de encabezado que muestra "Bienvenido, ABC", donde "ABC" es el nombre de usuario. Eso significa que se llamará al request.user para cada solicitud que resulte en aciertos de la base de datos una y otra vez.Django: ¿alguna forma de evitar la consulta de request.user en cada solicitud?

Pero una vez que un usuario ha iniciado sesión, debería ser capaz de almacenar su instancia user en su cookie y encriptarla. De esa manera puedo evitar golpear la base de datos repetidamente y simplemente recuperar request.user de la cookie.

¿Cómo modificaría Django para hacer esto? ¿Hay algún plugin de Django que haga lo que necesito?

Gracias

Respuesta

4

Desea utilizar el middleware de sesión y querrá leer el documentation. El middleware de sesión admite múltiples session engines. Lo ideal sería utilizar memcached o redis, pero you could write your own session engine to store all the data in the user's cookie. Una vez que habilita el middleware, está disponible como parte del objeto de solicitud. Interactúa con request.session, que actúa como un dict, por lo que es fácil de usar. Aquí hay un par de ejemplos de los documentos:

Esta vista simplista establece una variable has_commented en True después de que un usuario publique un comentario. No le permite a un usuario colocar un comentario más de una vez:

def post_comment(request, new_comment): 
    if request.session.get('has_commented', False): 
     return HttpResponse("You've already commented.") 
    c = comments.Comment(comment=new_comment) 
    c.save() 
    request.session['has_commented'] = True 
    return HttpResponse('Thanks for your comment!') 

Este simplistas ver los registros en un "miembro" del sitio:

def login(request): 
    m = Member.objects.get(username=request.POST['username']) 
    if m.password == request.POST['password']: 
     request.session['member_id'] = m.id 
     return HttpResponse("You're logged in.") 
    else: 
     return HttpResponse("Your username and password didn't match.") 
+0

Pero pensé que el objeto de la sesión todavía se almacena en el motor de la sesión de back-end, no en una cookie.Entonces, recuperar el objeto de la sesión aún requeriría golpear la base de datos, ¿no? – Continuation

+1

@Continuation No necesariamente, el motor de sesión admite muchos backends diferentes, uno de los cuales es un db-backend. Trataré de aclarar mi respuesta. – zeekay

1

Una vez que tenga el almacenamiento en caché adecuado el número de accesos de base de datos debe ser reducido significativamente, de nuevo - No estoy realmente y experto en almacenamiento en caché. Creo que sería una mala idea modificar request.user para resolver su problema. Creo que una mejor solución sería crear alguna utilidad, método o etiqueta de plantilla personalizada que intente cargar los datos de usuario requeridos de la cookie y devolver el resultado. Si los datos del usuario no se encuentran en la cookie, se debe realizar una llamada a request.user, guardar los datos en la cookie y luego devolver el resultado. Posiblemente podría utilizar una señal post_save para verificar cambios en los datos del usuario, de modo que pueda actualizar la cookie según sea necesario.

1

El usuario se une al objeto solicitud utilizando el Middleware de Autenticación proporcionado por django (django.contrib.auth.middleware). Utiliza una función la función get_user en django.contrib.auth. init para obtener al usuario del back-end que está utilizando. Puede cambiar fácilmente esta función para buscar al usuario en otra ubicación (por ejemplo, cookie).

Cuando un usuario inicia sesión, django coloca el ID de usuario en la sesión (request.session [SESSION_KEY] = user.id). Cuando un usuario cierra la sesión, borra la identificación del usuario de la sesión. Puede anular estas funciones de inicio de sesión y cierre de sesión para almacenar también un objeto de usuario en la cookie del navegador/borrar el objeto de usuario de la cookie en el navegador. Ambas funciones también están en django.contrib.auth. init

Vea aquí las cookies settting: Django Cookies, how can I set them?

5

Este olores de la sobre-optimización. Obtener un usuario del archivo db es un solo hit por solicitud, o posiblemente dos si también usa un modelo de perfil. Si su sitio es tal que dos consultas adicionales marcan una gran diferencia para el rendimiento, es posible que tenga problemas mayores.

+0

Totalmente de acuerdo. Esto no es lo suficientemente significativo como para preocuparse. Si realmente está preocupado por las consultas a la base de datos, ya debería estar utilizando algo como memcached, y eso lo hace aún más inútil. Si no estás utilizando memcached, detente e instálalo ahora. Solo eso se debe más a sus esfuerzos de optimización de BD que cualquier otra cosa que pueda modificar en Django. –

+0

No estoy muy seguro de que sea una sobre-optimización. Para un sitio web diseñado para más de 1 millón de usuarios. Creo que es bueno intentar evitar el golpe de la base de datos cuando sea posible. Esperanzadamente aquí, no es muy caro hacer eso. – jcyrss

Cuestiones relacionadas