2012-11-03 128 views
3

实现用户名不区分大小写:Django:默认情况下如何过滤使用username__iexact的用户?

我想含蓄暗示iexact查询user时:

user = User.objects.get(username = 'yugal') # Lowercase 
user.id # 1 

user = User.objects.get(username = 'YUgal') # Mixcase 
user.id # 1 

我怎样才能做到这一点? {某种方式UserManager}

注:

  • 此外,django.shortcuts.get_object_or_404似乎用它作为User.objects.get_query_set().all().get()。我们如何使它工作?
+0

btw:通常不会更好地将DB中的所有用户名以小写字母存储,并将它们查询为User.objects.get(username ='YuGal'.lower())? – yedpodtrzitko

+0

事情是:'.lower()'是我的代码的解决方案。但不适用于第三方应用程序。因为他们可能没有使用'.lower()' –

回答

0

我想我想出了一个办法来实现它适用于所有分贝查询:

###### QuerySet ####### 
def _filter_or_exclude(self, negate, *args, **kwargs): 
    if 'username' in kwargs: 
     kwargs['username__iexact'] = kwargs['username'] 
     del kwargs['username'] 
    if args or kwargs: 
     assert self.query.can_filter(),\ 
     "Cannot filter a query once a slice has been taken." 
    from django.db.models import Q 
    clone = self._clone() 
    if negate: 
     clone.query.add_q(~Q(*args, **kwargs)) 
    else: 
     clone.query.add_q(Q(*args, **kwargs)) 
    return clone 

from django.db.models.query import QuerySet 
QuerySet._filter_or_exclude = _filter_or_exclude 
###################### 

这解决了这个问题。

+0

这个解决方案可能会让一些人反感,但为了达到理想的效果 - 这是唯一可能的解决方案,但副作用最小。如果有人有更好的解决方案 - 请随时添加答案。请记住,它必须支持开箱即用的第三方应用程序。 –

3

明确:

user = User.objects.get(username__iexact='yugal') 

隐:覆盖User模型让您可以覆盖objects属性,在这里添加自定义iexact处理:

class MyUser(User): 

    class Meta: 
     proxy = True 


    objects = MyManager() 


class MyManager(UserManager): 

    def get(self, *args, **kwargs): 

     if 'username' in kwargs: 
      kwargs['username__iexact'] = kwargs['username'] 
      del kwargs['username'] 
     return super(MyManager, self).get(*args, **kwargs) 
+0

似乎是对的,让我试着回去。 –

+0

所有似乎工作,但它不与'django.shortcuts.get_object_or_404'工作。我们可以让这项工作为用户名假设'iexact'吗? –

+0

@YugalJindle你可以显示代码如何使用'get_object_or_404'? – yedpodtrzitko

相关问题