简体   繁体   English

Django:默认情况下执行不区分大小写的查找

[英]Django: Perform case-insensitive lookups by default

I need to perform case-insensitive queries on username by default when using the Django Auth framework. 我需要在使用Django Auth框架时默认对username执行不区分大小写的查询。

I tried fixing the issue by writing a custom subclass of Queryset and overriding the _filter_or_exclude method and then using that subclass in a custom manager for the User model- 我尝试通过编写Queryset的自定义子类并重写_filter_or_exclude方法然后在用户模型的自定义管理器中使用该子类来解决问题 -

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

But this approach didn't work and I am getting an weird error when I try doing User.objects.get(username='Foo') . 但是这种方法不起作用,当我尝试使用User.objects.get(username='Foo')时,我得到了一个奇怪的错误。

Any help would be appreciated. 任何帮助,将不胜感激。

Update : I am including the exact error that I am getting. 更新 :我包含了我得到的确切错误。

/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'

Update : By the way, I just wanted to mention that when I copy the logic inside my _filter_or_exclude method into the actual QuerySet class, it works flawlessly. 更新 :顺便说一句,我只想提一下,当我将_filter_or_exclude方法中的逻辑复制到实际的QuerySet类中时,它可以完美地工作。

You don't want to mess with internal features of Django classes. 你不想搞乱Django类的内部功能。 That way lies trouble with every upgrade in the future. 这种方式将来会遇到每次升级的麻烦。

If you want to change the way people authenticate, write a custom authentication backend. 如果要更改人员身份验证的方式,请编写自定义身份验证后端。

Here are two recipes. 这是两个食谱。

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

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

Both of these us email instead of username. 这两个人都是电子邮件而不是用户名。 It's not hard to use case-insensitive query instead of an email query. 使用不区分大小写的查询而不是电子邮件查询并不难。

Managers can't be added to classes with simple attribute assignment ( User.objects = MyManager() ). 无法将管理器添加到具有简单属性分配的类( User.objects = MyManager() )。 Look at the ModelBase metaclass (db/models/base.py) to see what all is done for you behind the scenes when you subclass Model. 查看ModelBase元类(db / models / base.py),看看在继承Model时幕后为您做了什么。

You should be able to make it work with User.add_to_class('objects', MyManager()) . 您应该能够使用User.add_to_class('objects', MyManager()) Alternatively, you could make a proxy subclass of User and add the manager there. 或者,您可以创建User的代理子类并在那里添加管理器。

Here's a recipe for the auth use case: Django : Case insensitive matching of username from auth user? 以下是auth用例的配方: Django:来自auth用户的用户名不区分大小写的匹配? You're probably best off using separate solutions for each of your use cases. 您可能最好为每个用例使用单独的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM