Comme je suis un lecteur impressionné de Stack Overflow je veux poser ma première question ici. Depuis que j'ai rencontré un problème avec un extrait et je ne sais pas si j'ai fait une erreur ou c'est un bug dans le code que j'utilise.Django fonctionnalité de recherche - bug avec requête de recherche de longueur 2
J'adapté ce code pour mon propre site:
http://blog.tkbe.org/archive/django-admin-search-functionality/
Il fonctionne très bien et il est vraiment un grand bout. Mais si ma requête de recherche a une longueur de 2, je pense que les résultats ne sont pas corrects.
Ainsi, par exemple si je recherche « re » au prénom et nom, je reçois les résultats suivants:
Mr. Tom Krem
Ms. Su Ker
Ce qui est assez étrange. Pour les requêtes de longueur> 2 je ne rencontre pas ce problème. Alors peut-être que cet article lit quelqu'un qui utilise l'extrait ci-dessus et peut me dire s'il rencontre le même problème.
Si personne d'autre ne rencontre le problème, je sais au moins que j'ai un bug quelque part dans mon code. Peut-être dans la forme que j'utilise, ou quelque chose est foiré dans le contexte de la requête.
Comment puis-je résoudre ce problème?
Edit 1:
L'étiquette d'inclusion:
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)
Le 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>
La vue:
@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))
Le formulaire de recherche de contact:
#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
Une autre édition:
J'utilise cet extrait pour trier le tableau. Probablement on devrait le savoir afin de comprendre le code affiché ci-dessus.
Puisque je ne peux pas publier de liens (protection anti-spam), je vais essayer de vous expliquer où le trouver. Aller sur Google. Tapez: django snippet table sort
Ensuite, il devrait être le deuxième coup. Trier les en-têtes de tableau. extrait nr. 308.
Edit: Ajouter la fonction 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' % '&'.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],
)
Quel est le backend de votre base de données? PostgreSQL? MySQL? Pourriez-vous poster votre version adaptée du code que vous pointez sur le blog ci-dessus? – cethegeek
J'utilise mysql. Je posterai la version adaptée du code ci-dessous. –
Vous devriez vraiment avoir tout le code que vous avez ajouté en guise de réponse à la question. Je ne cherche pas à pinailler, c'est juste que vous savez juste marqué votre question en réponse (ce qui réduit le trafic, et l'espoir d'obtenir une réponse), et confond les futurs lecteurs en pensant que tout ce code fait partie d'un solution à la question. – cethegeek