Quiero filtrar algunos objetos de base de datos por una cadena concatenada.Django ORM: filtro por atributo adicional
La consulta SQL normal sería:
SELECT concat(firstName, ' ', name) FROM person WHERE CONCAT(firstName, ' ', name) LIKE "a%";
En el modelo, he creado un gerente llamó 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)
También he configurado esto en mi modelo:
objects = managers.PersonObjects()
Ahora el acceso a fullName funciona para objetos individuales:
>>> p = models.Person.objects.get(pk=4)
>>> p.fullName
u'Fred Borminski'
Pero no funciona en un filtro:
>>> 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, (...)
Es esto un error o de una pieza? ¿Cómo puedo arreglar esto?
Gracias.
Lamentablemente, esto no funciona. Todavía se queja de no encontrar el atributo fullName. Sin embargo, la recuperación del atributo fullName de un objeto funciona directamente. ¿Este método 'extra' sobrescribe de alguna manera los atributos adicionales previamente establecidos del administrador? –
En realidad, esto tampoco funciona: 'models.Person.objects.extra (select = {'fullName':" CONCAT (firstName, '', name) "}, donde = ['fullName LIKE% s'], params = ['Alexei%']) '(Lanza" Columna desconocida 'fullName' en 'where clause' ". –
Lo siento por el comentario triple. La razón de este comportamiento es que Django, por supuesto, pasa el nombre completo como un alias, que no funciona con MySQL. Funcionaría en una cláusula 'HAVING', pero Django no parece apoyarlo. En su lugar, estoy usando los siguientes (no tan bonitos) modelos de compromiso:'. Person.objects.extra (where = ["CONCAT (firstName, '', name) LIKE% s"], params = ['Alexei%']) 'Gracias por su respuesta. –