2009-12-23 33 views
0

由于我是Stack Overflow的印象深刻的读者,我想在这里问我的第一个问题。由于我遇到了一个代码段的问题,我不知道我是否犯了一个错误,或者它是我正在使用的代码中的一个错误。Django搜索功能 - 与长度为2的搜索查询相关的错误

我适应此代码为我自己的网站:

http://blog.tkbe.org/archive/django-admin-search-functionality/

它工作正常,这真是一个伟大的片段。 但是,如果我的搜索查询长度为2,我认为结果不正确。

因此,举例来说,如果我搜索“重”的姓氏和名字,我得到如下结果:

Mr. Tom Krem 
Ms. Su Ker 

这是非常奇怪的。对于长度大于2的查询,我不会遇到这个问题。 所以,也许这篇文章读了一些使用上面代码片段的人,并告诉我他/她是否遇到同样的问题。

如果没有人遇到问题,至少我知道我的代码中存在一处错误。也许在我正在使用的形式中,或者在请求上下文中弄乱了某些东西。

我该如何解决这个问题?

编辑1:

列入标签:

from django import template 
from crm.views import SEARCH_VAR 

def my_search_form(context): 
    return { 
     'context': context, 
     'search_var': SEARCH_VAR 
    } 

register = template.Library() 
register.inclusion_tag('custom_utilities/my_search_form.html')(my_search_form) 

my_search_form.html

<div id="toolbar"><form 
     id="changelist-search" 
     action="" 
     method="get"> 
     <div><!-- DIV needed for valid HTML --> 
      <label 
       for="searchbar"><img src="{{ context.media_url }}/crm/img/search.png" 
       class="icon" 
       alt="Search" /></label> 
      <input 
       type="text" 
       size="40" 
       name="{{ search_var }}" 
       value="{{ context.query }}" 
       id="searchbar" /> 
      <input type="submit" value="Search" /> 
     </div> 
    </form> 
</div> 
<script 
    type="text/javascript">document.getElementById("searchbar").focus(); 
</script> 

视图:

@login_required 
def crm_contacts(request): 
    query = request.GET.get('q', '') 
    #pass additional params to the SortHeaders function 
    #the additional params will be part of the header <a href...> 
    #e.g. use it for pagination/use it to provide the query string 
    additional_params_dict = {'q': query} 
    foundContacts = search_contact(request,query) 
    sort_headers = SortHeaders(request, LIST_HEADERS, default_order_field=1, additional_params=additional_params_dict) 
    if foundContacts is not None: 
     contact_list = foundContacts.order_by(sort_headers.get_order_by()) 
    else: 
     contact_list = Contact.objects.order_by(sort_headers.get_order_by()) 
    context = { 
     'contact_list' : contact_list, 
     'headers': list(sort_headers.headers()), 
     'query' : query, 
    } 
    return render_to_response("crm/contact_list.html", context, 
          context_instance=RequestContext(request)) 

接触搜索表单:

#models 
from crm.models import Contact 
from django.db.models import Q 

''' 
A search form from 
http://blog.tkbe.org/archive/django-admin-search-functionality/ 
adapted to search for contacts. 
''' 
def search_contact(request,terms=None): 
    if terms is None: 
     return Contact.objects.all() 
    query = Contact.objects 
    for term in terms: 
     query = query.filter(
      Q(first_name__icontains=term) 
      | Q(last_name__icontains=term)) 
    return query 

另一个编辑:

我用这个片段进行排序表。为了理解上面的代码,大概人们应该知道这一点。

由于我无法发布链接(垃圾邮件保护),我会尝试解释在哪里可以找到它。转到Google。输入:django snippet表排序

然后它应该是第二次打击。排序表头。 snippet nr。 308.

编辑:添加SortHeaders()函数

ORDER_VAR = 'o' 
ORDER_TYPE_VAR = 'ot' 

class SortHeaders: 
    """ 
    Handles generation of an argument for the Django ORM's 
    ``order_by`` method and generation of table headers which reflect 
    the currently selected sort, based on defined table headers with 
    matching sort criteria. 

    Based in part on the Django Admin application's ``ChangeList`` 
    functionality. 
    """ 
    def __init__(self, request, headers, default_order_field=None, 
      default_order_type='asc', additional_params=None): 
     """ 
     request 
      The request currently being processed - the current sort 
      order field and type are determined based on GET 
      parameters. 

     headers 
      A list of two-tuples of header text and matching ordering 
      criteria for use with the Django ORM's ``order_by`` 
      method. A criterion of ``None`` indicates that a header 
      is not sortable. 

     default_order_field 
      The index of the header definition to be used for default 
      ordering and when an invalid or non-sortable header is 
      specified in GET parameters. If not specified, the index 
      of the first sortable header will be used. 

     default_order_type 
      The default type of ordering used - must be one of 
      ``'asc`` or ``'desc'``. 

     additional_params: 
      Query parameters which should always appear in sort links, 
      specified as a dictionary mapping parameter names to 
      values. For example, this might contain the current page 
      number if you're sorting a paginated list of items. 
     """ 
     if default_order_field is None: 
      for i, (header, query_lookup) in enumerate(headers): 
       if query_lookup is not None: 
        default_order_field = i 
        break 
     if default_order_field is None: 
      raise AttributeError('No default_order_field was specified and none of the header definitions given were sortable.') 
     if default_order_type not in ('asc', 'desc'): 
      raise AttributeError('If given, default_order_type must be one of \'asc\' or \'desc\'.') 
     if additional_params is None: additional_params = {} 

     self.header_defs = headers 
     self.additional_params = additional_params 
     self.order_field, self.order_type = default_order_field, default_order_type 

     # Determine order field and order type for the current request 
     params = dict(request.GET.items()) 
     if ORDER_VAR in params: 
      try: 
       new_order_field = int(params[ORDER_VAR]) 
       if headers[new_order_field][1] is not None: 
        self.order_field = new_order_field 
      except (IndexError, ValueError): 
       pass # Use the default 
     if ORDER_TYPE_VAR in params and params[ORDER_TYPE_VAR] in ('asc', 'desc'): 
      self.order_type = params[ORDER_TYPE_VAR] 

    def headers(self): 
     """ 
     Generates dicts containing header and sort link details for 
     all defined headers. 
     """ 
     for i, (header, order_criterion) in enumerate(self.header_defs): 
      th_classes = [] 
      new_order_type = 'asc' 
      if i == self.order_field: 
       th_classes.append('sorted %sending' % self.order_type) 
       new_order_type = {'asc': 'desc', 'desc': 'asc'}[self.order_type] 
      yield { 
       'text': header, 
       'sortable': order_criterion is not None, 
       'url': self.get_query_string({ORDER_VAR: i, ORDER_TYPE_VAR: new_order_type}), 
       'class_attr': (th_classes and ' class="%s"' % ' '.join(th_classes) or ''), 
      } 

    def get_query_string(self, params): 
     """ 
     Creates a query string from the given dictionary of 
     parameters, including any additonal parameters which should 
     always be present. 
     """ 
     params.update(self.additional_params) 
     return '?%s' % '&amp;'.join(['%s=%s' % (param, value) \ 
            for param, value in params.items()]) 

    def get_order_by(self): 
     """ 
     Creates an ordering criterion based on the current order 
     field and order type, for use with the Django ORM's 
     ``order_by`` method. 
     """ 
     return '%s%s' % (
      self.order_type == 'desc' and '-' or '', 
      self.header_defs[self.order_field][1], 
     ) 
+0

什么是您的数据库后端? PostgreSQL的? MySQL的?您可以发布您在上面博客上指出的代码的修改版本吗? – cethegeek 2009-12-23 16:17:13

+0

我使用mysql。我将发布下面的代码的修改版本。 – 2009-12-23 16:54:48

+0

你真的应该把你添加的所有代码作为答案作为对问题的修改。我并没有试图挑剔,只是你知道只是将你的问题标记为答案(这减少了它的流量,并希望得到答案),并混淆了未来的读者,认为所有代码都是解决问题的方法。 – cethegeek 2009-12-23 17:37:06

回答

0

如果运行manage.py shell然后:

>>> from crm.models import Contact 
>>> from django.db.models import Q 
>>> list=Contact.objects.filter(Q(first_name__icontains='re')|Q(last_name__icontains='re')) 
>>> print list 

的输出是什么?


编辑:对,所以如果你尝试:

>>> list=Contact.objects.filter(Q(first_name__icontains='mot')|Q(last_name__icontains='mot')) 
>>> print list 

(我试图缩小对是给你的问题的条款,我看到了你最后的评论)

什么是输出?


编辑:如果上述两种查询在外壳的工作,别的某处修改您的查询集,并增加了一些附加条件......

你肯定sort_headers()没有更多的修改查询集不仅仅是一个命令的条款?您可以在您的问题上发布sort_headers()吗?

+0

输出是 - >汤姆克雷姆先生 这将是正确的!因此在传输查询字符串时可能存在问题? – 2009-12-23 18:08:05

+0

确定上述查询都可以正常工作。因此可能在某处我可能会添加一些内容到我的查询中。我明天会检查密码。到现在为止;-)非常感谢您的帮助! – 2009-12-23 22:39:16

+0

我想我发现了这个问题。这是查询中的术语。似乎每个字符都被过滤并添加到结果集中。!? 查询= request.GET.get( 'Q', '') foundContacts = search_contact(请求,查询) >>> >>> QueryResult中= Contact.objects >>>对于术语在查询: 。 ..打印术语 ... QueryResult中= queryresult.filter( ... Q(first_name__icontains =术语) ... | Q(last_name__icontains =术语)) ... 米 ö 吨 >>>打印查询结果 [<联系人:Tom Tom>,<联系人:Tom Tom>,<联系人:Tom Tom>,<联系人:Tom Tom>,<联系人:Tom Tom>,<联系人:Tom Tom>,... – 2009-12-23 23:07:55