2009-02-10 21 views
6

Necesito realizar consultas que no distingan entre mayúsculas y minúsculas en username de forma predeterminada cuando uso el marco de Django Auth.Django: realizar búsquedas en mayúsculas y minúsculas de manera predeterminada

He intentado solucionar la incidencia escribiendo una subclase personalizada de Queryset y reemplazando el método _filter_or_exclude y luego usar esa subclase en un gestor personalizado para el usuario modelo-

from django.db.models import Manager 
from django.db.models.query import QuerySet 
from django.contrib.auth.models import UserManager 

class MyQuerySet(QuerySet): 
    def _filter_or_exclude(self, negate, *args, **kwargs): 
     if 'username' in kwargs: 
      kwargs['username__iexact'] = kwargs['username'] 
      del kwargs['username'] 
     return super(MyQuerySet, self)._filter_or_exclude(negate, *args, **kwargs) 

class MyUserManager(UserManager): 
    def get_query_set(self): 
     return MyQuerySet(self.model) 

User.objects = MyUserManager() 

Pero este enfoque no lo hicieron trabajo y recibo un extraño error cuando intento hacer User.objects.get(username='Foo').

Cualquier ayuda sería apreciada.

Actualización: Estoy incluyendo el error exacto que estoy recibiendo.

/usr/lib/python2.5/site-packages/django/db/models/query.py in get(self, *args, **kwargs) 
    295   keyword arguments. 
    296   """ 
--> 297   clone = self.filter(*args, **kwargs) 
    298   num = len(clone) 
    299   if num == 1: 

/usr/lib/python2.5/site-packages/django/db/models/query.py in filter(self, *args, **kwargs) 
    481   set. 
    482   """ 
--> 483   return self._filter_or_exclude(False, *args, **kwargs) 
    484 
    485  def exclude(self, *args, **kwargs): 

/home/ghoseb/src/git/ocricket.git/ocricket/user/models.py in _filter_or_exclude(self, negate, *args, **kwargs) 
    38    kwargs['username__iexact'] = kwargs['username'] 
    39    del kwargs['username'] 
---> 40   return super(MyQuerySet, self)._filter_or_exclude(negate, *args, **kwargs) 
    41 
    42 class MyUserManager(UserManager): 

/usr/lib/python2.5/site-packages/django/db/models/query.py in _filter_or_exclude(self, negate, *args, **kwargs) 
    499    clone.query.add_q(~Q(*args, **kwargs)) 
    500   else: 
--> 501    clone.query.add_q(Q(*args, **kwargs)) 
    502   return clone 
    503 

/usr/lib/python2.5/django/db/models/sql/query.py in add_q(self, q_object, used_aliases) 

/usr/lib/python2.5/django/db/models/sql/query.py in add_filter(self, filter_expr, connector, negate, trim, can_reuse, process_extras) 

/usr/lib/python2.5/django/db/models/sql/query.py in get_meta(self) 

<type 'exceptions.AttributeError'>: 'NoneType' object has no attribute '_meta' 

actualización: Por cierto, sólo quería mencionar que cuando copio la lógica dentro de mi método _filter_or_exclude en la clase real QuerySet, funciona perfectamente.

+0

¿Podría publicar el error también? –

+0

Agregado. Gracias por recordar. –

+0

Extraño error. ¿Puedes verificar que obtienes este error en este código exacto? No hay métodos adicionales en QuerySet o Manager reemplazados, y no hay subclases intermedias adicionales en la jerarquía de herencia, no hay mixins adicionales? –

Respuesta

4

Los administradores no se pueden agregar a las clases con asignación de atributo simple (User.objects = MyManager()). Mire la metaclase de ModelBase (db/models/base.py) para ver qué se hace todo detrás de las escenas cuando se subclase el Modelo.

Debería poder hacer que funcione con User.add_to_class('objects', MyManager()). Alternativamente, puede hacer un proxy subclass de Usuario y agregar el administrador allí.

+0

No estoy seguro de que se permita o tenga sentido una subclase abstracta de una clase concreta, pero un modelo proxy funcionaría bien en esta situación. –

+0

@rz Los modelos de Proxy no existían cuando se escribió esta respuesta :-) Lo actualizaré. –

+0

¡genial! supongo que debería haber hecho uso de mis superpoderes de edición recién adquiridos y simplemente lo hice por ti. Por cierto, Carl, aparte de la forma en que estaba agregando el administrador, ¿es sensato este enfoque para obtener una tienda sensible a mayúsculas y minúsculas que no distinga entre mayúsculas y minúsculas? –

5

No quiere meterse con las características internas de las clases de Django. De esa manera se encuentran problemas con cada actualización en el futuro.

Si desea cambiar la forma en que las personas se autentican, escriba un servidor de autenticación personalizado.

Aquí hay dos recetas.

http://www.davidcramer.net/code/224/logging-in-with-email-addresses-in-django.html

http://www.djangosnippets.org/snippets/577/

Ambos nosotros por correo electrónico en lugar del nombre de usuario. No es difícil usar una consulta que no distinga entre mayúsculas y minúsculas en lugar de una consulta de correo electrónico.

+0

Bueno, soy muy consciente de los back-end personalizados de autenticación, pero no No necesito esto para (solo) auth, pero para otras cosas, como nombres de usuario usados ​​en URLs, etc. –

Cuestiones relacionadas