2017-10-11 6 views
0

Je souhaite rechercher plusieurs champs dans de nombreux modèles. Je ne veux pas utiliser d'autres applications comme 'Haystack' uniquement Django pur. Par exemple:Champs de recherche Django dans plusieurs modèles

# models.py 

class Person(models.Model): 
    first_name = models.CharField("First name", max_length=255) 
    last_name = models.CharField("Last name", max_length=255) 
    # other fields 


class Restaurant(models.Model): 
    restaurant_name = models.CharField("Restaurant name", max_length=255) 
    # other fields 


class Pizza(models.Model): 
    pizza_name = models.CharField("Pizza name", max_length=255) 
    # other fields 

Lorsque je tape un 'Tonny' je devrais obtenir:

  • "Tonny Montana" de Person modèle
  • "Le restaurant de Tonny" de Restaurant modèle
  • « Tonny de Pizza spéciale "du modèle pizza.

Répondre

1

Une solution consiste à interroger tous les modèles

# Look up Q objects for combining different fields in a single query 
from django.db.models import Q 
people = Person.objects.filter(Q(first_name__contains=query) | Q(last_name__contains=query) 
restaurants = Restaurant.objects.filter(restaurant_name__contains=query) 
pizzas = Pizza.objects.filter(pizza_name__contains=query) 

ensuite combiner les résultats, si vous voulez

from itertools import chain 
results = chain(people, restaurants, pizzas) 

Ok, bien sûr, voici une solution plus générique. Rechercher tous les CharFields dans tous les modèles:

search_models = [] # Add your models here, in any way you find best. 
search_results = [] 
for model in search_models: 
    fields = [x for x in model._meta.fields if isinstance(x, django.db.models.CharField)] 
    search_queries = [Q(**{x.name + "__contains" : search_query}) for x in fields] 
    q_object = Q() 
    for query in search_queries: 
     q_object = q_object | query 

    results = model.objects.filter(q_object) 
    search_results.append(results) 

Cela vous donnera une liste de tous les QuerySets, vous pouvez modeler à un format que vous choisissez de travailler avec.

Pour obtenir une liste des modèles pour remplir search_models, vous pouvez le faire manuellement, ou utiliser quelque chose comme get_models. Lisez les documents pour plus d'informations sur comment cela fonctionne.

+0

Merci pour une réponse rapide. C'est utile, mais dans mon projet j'ai plus de 30 modèles avec plusieurs champs et je me demande s'il y a moyen de ne pas taper le filtre pour tous les champs dans les modèles? – Konrados

+0

Ajout d'une solution plus générique. – user6731765