Je souhaite filtrer certains objets de base de données par une chaîne concaténée.Django ORM: Filtrer par attribut supplémentaire
La requête SQL normale serait:
SELECT concat(firstName, ' ', name) FROM person WHERE CONCAT(firstName, ' ', name) LIKE "a%";
Dans le modèle, j'ai créé un gestionnaire appelé PersonObjects:
class PersonObjects(Manager):
attrs = {
'fullName': "CONCAT(firstName, ' ', name)"
}
def get_query_set(self):
return super(PersonObjects, self).get_query_set().extra(
select=self.attrs)
J'ai aussi Configuré dans mon modèle:
objects = managers.PersonObjects()
L'accès à fullName fonctionne maintenant pour les objets uniques:
>>> p = models.Person.objects.get(pk=4)
>>> p.fullName
u'Fred Borminski'
Mais cela ne fonctionne pas dans un filtre:
>>> p = models.Person.objects.filter(fullName__startswith='Alexei')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/site-packages/django/db/models/manager.py", line 141, in filter
return self.get_query_set().filter(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 550, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/lib/python2.7/site-packages/django/db/models/query.py", line 568, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1128, in add_q
can_reuse=used_aliases)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1026, in add_filter
negate=negate, process_extras=process_extras)
File "/usr/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1191, in setup_joins
"Choices are: %s" % (name, ", ".join(names)))
FieldError: Cannot resolve keyword 'fullName' into field. Choices are: firstName, gender, name, (...)
Est-ce un bug ou une fonctionnalité? Comment puis-je réparer cela?
Merci.
Malheureusement, cela ne fonctionne pas. Il se plaint toujours de ne pas trouver l'attribut fullName. Récupérer l'attribut fullName d'un objet fonctionne directement. Est-ce que cette méthode 'extra' remplace en quelque sorte les attributs supplémentaires précédemment définis par le gestionnaire? –
En fait cela ne fonctionne pas non plus: 'models.Person.objects.extra (select = {'fullName':" CONCAT (prénom, '', nom) "}, où = ['fullName LIKE% s'], params = ['Alexei%']) '(Il lance" Unknown column 'fullName' dans 'where clause' ". –
Je suis désolé pour le triple commentaire. La raison de ce comportement est que Django passe bien sûr le fullName en tant que alias, qui ne fonctionne pas avec MySQL Cela fonctionnerait dans une clause 'HAVING', mais cela ne semble pas être supporté par Django, mais j'utilise le compromis suivant (pas si beau):' models. Person.objects.extra (où = ["CONCAT (prénom, '', nom) LIKE% s"], params = ['Alexei%']) '. Merci pour votre réponse. –