1
votes

Django: recherche dans les modèles associés

Bonjour, je souhaite créer un formulaire de recherche simple qui permettra d'obtenir des données à partir de modèles associés.

J'ai 3 modèles:

{% block content %}
   {%for user in users %}
      {{user.id }} {{user.name}} {{user.surname}}
      {% for email in user.email_set.all %}
         {{email}}
      {% endfor %}
    {% endfor %}

dans ma vue d'accueil j'ai :

people= above query
emails = Email.objects.filter(email__icontains=query)
context = chain(people,emails)

Et ça marche bien, mais j'aimerais aussi chercher dans les e-mails et les téléphones (la personne peut avoir peu d'e-mails et de téléphone). Si dans ma requête j'utilise un autre OR (|), j'ai une erreur, je ne peux pas combiner 2 modèles en une seule requête. Je veux aussi essayer avec chain:

def home(request):
    people = Person.objects.all()
    query = request.GET.get("q")
    if query:
        people = Person.objects.filter(Q(name__icontains=query)|Q(surname__icontains=query)|
                 Q(emails__contains=query)|Q(phones__icontains=query))
    //when I try emails_email__icontains=query I get error about no such fields

    return render(request,'app/home.html',{'users': people})

Malheureusement, cette solution ne fonctionne pas non plus. Comment puis-je résoudre ce problème?

MODIFIER: TEMPLATE

class Person(models.Model):
    name = models.CharField()
    surname = models.CharField()

class Phone(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE,related_name="phones")
    phone = models.CharField(0

class Email(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE, related_name="emails")
    email = models.EmailField()


0 commentaires

3 Réponses :


1
votes

vous pouvez utiliser Q ici :

modèles:

from django.db.models import Q

def home(request):
    people= Person.objects.all()
    query - request.GET.get("q")
    if query:
        people = Person.objects.filter(Q(name__icontains=query) | Q(surname__icontains=query) | Q(emails__email__icontains=query) | Q(phones__phone__icontains=query))

    return render(request,'app/home.html',{'users': people})

vues:

class Phone(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE, related_name="phones")
    phone = models.CharField(0

class Email(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE, related_name="emails")
    email = models.EmailField()

utiliser la chaîne


2 commentaires

Je comprends qu'après avoir utilisé Q, je peux: Person.objects.filter (Q (emails icontains = query))?


vous pouvez le faire comme ceci: Person.objcets.filter (Q (emails__email__icontains = query))



1
votes

essayez ceci

​​dans models.py

{% block content %}
{% for user in users %}
    {{user.id }} {{user.name}} {{user.surname}}
    {% for email in user.b.all %}
       {{email.email}}
    {% endfor %}
{% endfor %}

dans le filtre

from django.db.models import Q

people = Person.objects.filter(Q(name__icontains=query)|Q(surname__icontains=query)|Q(b__email__icontains=query))

dans le modèle

class Person(models.Model):
    name = models.CharField()
    surname = models.CharField()

class Phone(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE, related_name='a')
    phone = models.CharField(0

class Email(models.Model):
    person = models.ForeignKey(Person,on_delete=models.CASCADE, related_name='b')
    email = models.EmailField()

j'espère que cela aidera


5 commentaires

Eh bien, lorsque j'ai ajouté related_name à mes modèles, ils ne sont pas affichés dans mon fichier html. Avant j'avais: {% pour l'email dans user.email_set.all%} qui fonctionnait. Et après les changements ne l'est pas. J'ai essayé {% pour l'e-mail dans user.emails%}, mais rien ne s'affiche


J'ai ajouté mon modèle


ainsi les téléphones et les e-mails ATM sont affichés. Mais quand je veux rechercher, j'obtiens FieldError - Le champ associé a une recherche non valide: icontains


@Frendom utilise un double trait de soulignement emails__email__icontains


Ça marche, merci. Le seul problème est que si l'utilisateur a peu de courriels ou de téléphones, il s'affiche plusieurs fois après la recherche



1
votes

Pour ce que je comprends de la question, vous avez essentiellement besoin d'une union de personnes ayant la requête de recherche sous forme d'e-mail ou de téléphone.

    Person.objects.filter(Q(mobile__icontains=query)|Q(email__icontains=query))

La requête ci-dessus renverra la liste des objets Person en conséquence. Il s'agit essentiellement d'une recherche inversée qui recherchera tous les modèles ayant Person comme clé étrangère et ayant des champs à savoir mobile et email.


0 commentaires