Filtro de Django Queryset después de una concatenación de dos columnas

¿Hay alguna forma de filtrar un modelo utilizando una concatenación de dos de sus columnas? Mi modelo es así:

class Item(models.Model): series = models.CharField(max_length=50) number = models.CharField(max_length=50) 

Lo que necesito es filtrar después de la concatenación de las dos columnas, si un usuario ingresa A123, quiero poder encontrar cualquier artículo que tenga una serie y un número como% A y 123% o% A1 y 23%. ¿Es esto posible usando el modelos django? ¿O es posible con sql crudo? Preferiría no construir una nueva columna con la concatenación.

Sí, eso es posible; deberá annotate el QuerySet con la concatenación de los campos, y esa nueva columna “virtual” podrá filtrar.

Documentación relevante sobre el filtrado de anotaciones.

utilizando Concat como una función de anotación

Además de lo dicho anteriormente, ejemplo:

 from django.db.models import Value from django.db.models.functions import Concat queryset = Item.objects.annotate(search_name=Concat('series', Value(' '), 'number')) # then you can filter: queryset.filter(search_name__icontains='whatever text') 

Encontré mi camino, si vas a usar algunas de las solicitudes de ajax, entonces empecé a usar así

en views.py

 AllUser = User.objects.all() users = [] for i in AllUser: if query in i.get_full_name(): users += [{'first_name':i.first_name,'last_name':i.last_name,'full_name':i.get_full_name()}] qUser = users 

y en la página ajax devuelta (en mi caso ‘searchajax.html’)

 {% if qUser %} {% for i in qUser %} 

{{ i.full_name }}

{% endfor %} {% endif %}

funciona muy bien para mi :))

Otra forma es usando anotar.

 from django.db.models import CharField, Value as V from django.db.models.functions import Concat author = User.objects.annotate(screen_name=Concat('first_name', V(' ') ,'last_name')) for i in author: print i.screen_name 

también hace el mismo trabajo :))

Aquí hay un ejemplo completo que muestra cómo filtrar en función de la función annotate() y una expresión Concat .

 # Tested with Django 1.9.2 import sys import django from django.apps import apps from django.apps.config import AppConfig from django.conf import settings from django.db import connections, models, DEFAULT_DB_ALIAS from django.db.models.base import ModelBase from django.db.models.functions import Concat NAME = 'udjango' def main(): setup() class Item(models.Model): series = models.CharField(max_length=50) number = models.CharField(max_length=50) syncdb(Item) Item.objects.create(series='A', number='1234') Item.objects.create(series='A', number='1230') Item.objects.create(series='A', number='9999') Item.objects.create(series='B', number='1234') print(Item.objects.annotate( search=Concat('series', 'number')).filter( search__icontains='A123').values_list('series', 'number')) # >>> [(u'A', u'1234'), (u'A', u'1230')] def setup(): DB_FILE = NAME + '.db' with open(DB_FILE, 'w'): pass # wipe the database settings.configure( DEBUG=True, DATABASES={ DEFAULT_DB_ALIAS: { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': DB_FILE}}, LOGGING={'version': 1, 'disable_existing_loggers': False, 'formatters': { 'debug': { 'format': '%(asctime)s[%(levelname)s]' '%(name)s.%(funcName)s(): %(message)s', 'datefmt': '%Y-%m-%d %H:%M:%S'}}, 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'debug'}}, 'root': { 'handlers': ['console'], 'level': 'WARN'}, 'loggers': { "django.db": {"level": "WARN"}}}) app_config = AppConfig(NAME, sys.modules['__main__']) apps.populate([app_config]) django.setup() original_new_func = ModelBase.__new__ @staticmethod def patched_new(cls, name, bases, attrs): if 'Meta' not in attrs: class Meta: app_label = NAME attrs['Meta'] = Meta return original_new_func(cls, name, bases, attrs) ModelBase.__new__ = patched_new def syncdb(model): """ Standard syncdb expects models to be in reliable locations. Based on https://github.com/django/django/blob/1.9.3 /django/core/management/commands/migrate.py#L285 """ connection = connections[DEFAULT_DB_ALIAS] with connection.schema_editor() as editor: editor.create_model(model) main()