Функциональность поиска в Django - ошибка с поисковым запросом длины 2 - PullRequest
0 голосов
/ 23 декабря 2009

Поскольку я впечатленный читатель Stack Overflow, я хочу задать свой первый вопрос здесь. Так как я столкнулся с проблемой с фрагментом, и я не знаю, сделал ли я ошибку или это ошибка в используемом коде.

Я адаптировал этот код для своего сайта:

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

Он отлично работает, и это действительно отличный фрагмент. Но если мой поисковый запрос имеет длину 2, я думаю, что результаты не верны.

Так, например, если я ищу «re» по имени и фамилии, я получаю следующие результаты:

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

Тогда это должен быть второй удар. Сортировать заголовки таблицы. фрагмент номера 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],
        )

1 Ответ

0 голосов
/ 23 декабря 2009

Если вы запустите 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() на ваш вопрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...