7
votes

Y a-t-il un moyen de faire un cas insensible à une question à Django?

Près de chaque type de recherche à Django a une version insensible à la casse, sauf dans, il apparaît.

Ceci est un problème car parfois je dois faire une recherche où je suis certain que le cas sera incorrect. P>

Products.objects.filter(code__in=[user_entered_data_as_list])


1 commentaires

Je trouve cela particulier. Au moins sur MySQL, il semble que la __in recherche soit insensible à l'affaire.


7 Réponses :


1
votes

S'il ne créera pas de conflit, une solution de contournement éventuelle peut transformer les chaînes en majuscules ou en minuscules lorsque l'objet est enregistré et dans le filtre .


1 commentaires

Malheureusement, les objets recherchés peuvent être des cas minuscules ou mixtes, et il n'est pas possible de restreindre cela.



9
votes

J'ai travaillé autour de cela en faisant la base de données MySQL elle-même insensible à la casse. Je doute que les personnes de Django soient intéressées à ajouter cela comme une caractéristique ou à fournir des documents sur la manière de fournir votre propre recherche sur le terrain (en supposant que cela soit même possible sans fournir de code pour chaque backend de DB)

Voici un moyen de faire Certes, c'est CLUNKY. P>

products = Product.objects.filter(**normal_filters_here)
results = Product.objects.none()
for d in user_entered_data_as_list:
    results |= products.filter(code__iexact=d)


0 commentaires

0
votes

Un peu plus élégant serait ceci: xxx


3 commentaires

Je ne vois pas comment c'est plus élégant. Produits.ObjectS.All () peut revenir mille milliers de lignes, puis vous allez le filtrer en dehors de la base de données, puis le retourner comme une liste, pas même comme une requête, ce qui signifie que vous Impossible de trier (facilement) ou d'effectuer des filtres supplémentaires dessus. Il suffit de réaliser que vous êtes également en boucle via user_entered_data_as_entered_data_as_entered_data_as_entered_data_as_list Chaque fois Alors oui tout le monde, faites pas Utilisez cette technique à moins que votre table soit très très petite.


Il suffit de faire un test, votre méthode prend environ 200 fois plus longtemps pour une table avec 30k + enregistrements: Pastebin.com/R78P0PDQ


Ce n'est pas efficace, bien que vous puissiez essayer d'utiliser un générateur au lieu d'une liste simple.



1
votes

Voici une solution qui ne nécessite pas de valeurs de DB préparées par cas. De plus, il fait un filtrage sur le côté moteur DB, ce qui signifie beaucoup plus de performances que d'itération de Objets.All () CODE>.

MyModel.objects.extra(
    select={'lower_' + fieldname: 'lower(' + fieldname + ')'}
).filter('lover_' + fieldname + '__in'=[x.lower() for x in iterable])


0 commentaires

1
votes

Une autre solution - bien que brut - est d'inclure les différents cas des chaînes d'origine dans l'argument de liste au filtre "dans". Par exemple: au lieu de ['A', 'B', 'C'], utilisez ['A', 'B', 'B', 'C', 'A', 'B', 'C'] "

Voici une fonction qui construit une telle liste d'une liste de chaînes: xxx


0 commentaires

2
votes

Si votre base de données est MySQL, Django traite dans les requêtes de l'affaire insensitative. Bien que je ne sois pas sûr d'autres autres

edit 1: xxx

donnera le résultat suivant dans lequel le nom de la ville est

TOKIO ou tokio ou tokio ou paris < / Strong> Paris ou Paris


3 commentaires

Pouvez-vous expliquer un peu plus?


Ce que je voulais dire, c'est que si vous utilisez la base de données MySQL avec le système Django ORM, toutes les questions sont insensibles.


Pour @Dietermaemken, j'ai édité ma réponse avec un exemple.



1
votes

une recherche avec < Code> q objet peut être conçu pour toucher la base de données une seule fois: xxx


0 commentaires