Searching for a field contained in several models

2

I have a manager in my project, which is to do TAGS, and on the front of my system the user will search for a tag, and it will return everything related to that tag.

Follow the models.py:

from django.db import models
from django.utils import timezone
from taggit.managers import TaggableManager

class Noticia(models.Model):
    id = models.BigAutoField(primary_key=True)
    autor = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    titulo = models.CharField(max_length=255)
    subtitulo = models.CharField(max_length=255)
    fonte = models.CharField(max_length=255)
    veiculo = models.CharField(max_length=255)
    data = models.DateTimeField()
    integra = models.TextField()
    curtidas = models.IntegerField()
    tags = TaggableManager()

    def __str__(self):
        return self.titulo

    class Meta:
        verbose_name = 'Notícia'
        verbose_name_plural = 'Notícias'

    # def __str__(self):
    #     return self.titulo

class Dados(models.Model):
    dado = models.FloatField()
    texto = models.CharField(max_length=255)
    fonte = models.CharField(max_length=80)
    anotacao = models.CharField(max_length=255, blank=True)
    tags = TaggableManager()
    relacionado = models.ForeignKey(Noticia, on_delete=models.CASCADE)

    class Meta:
        verbose_name = 'Dados da noticía'
        verbose_name_plural = 'Dados das notícias'

class Case(models.Model):
    titulo = models.CharField(max_length=255)
    empresa = models.CharField(max_length=255)
    problemas = models.TextField()
    resultados = models.TextField()
    tags = TaggableManager()

    class Meta:
        verbose_name = 'Case'
        verbose_name_plural = 'Cases'

class Benchmarking(models.Model):
    titulo = models.CharField(max_length=255)
    empresa = models.CharField(max_length=255)
    aprendizados = models.TextField()
    tags = TaggableManager()

    class Meta:
        verbose_name = 'Benchmarking'

The TAG, is this "tags = TaggableManager ()". And I put it in several tables.

I want to type for example: Overflow, and it will return all those items that have been registered to the overflow tag

My view filtering the tags: (it's the way it used to be, filtering only on news)

def getdb(request):
    noticias = Noticia.objects.all()
    _tags = request.GET.get('search')
    tags = ''
    if _tags:
        tags = _tags.split(',')

    noticias = noticias.filter(tags__name__in=tags)
    
asked by anonymous 20.11.2018 / 19:05

1 answer

1

In order to filter efficiently you have to pass the resulting object of your search as context to your view.

views.py

def getdb(request):
    _tags = request.GET.get('search')
    if _tags:
        tags = _tags.split(',')

    noticias = Noticia.objects.all().filter(tags__name__in=[_tag])
    #Pesquisa todos os objetos Noticia que contem sua tag

    context = {
        'noticias': noticias,
    }

    return render(request, 'seuhtml.html', context)

Finally, just display your resulting object in your template

suhtml.html

{% for item in noticias %}
    {{item.autor}}
    {{item.titulo}}
    {{item.subtitulo}}
    ...
{% endfor %}

To filter for all objects in your model, you need to maintain a relationship between them. As in your dados object, since the relacionado = models.ForeignKey(Noticia, on_delete=models.CASCADE) relationship exists the same becomes available in your view:

{% for item in noticias %}
    {{item.autor}}
    {{item.titulo}}
    {{item.subtitulo}}
    {{item.dados.texto}}
    {{item.dados.fonte}}
    ...
{% endfor %}

Set the appropriate relationship between the templates you want to filter on and they will be available through your main query:

noticias = Noticia.objects.all().filter(tags__name__in=[_tag]) .

Note that once the relationships are well established you only need to have a tag in your news ( tags = TaggableManager() ) since it is only by it that you will base yourself to get the rest.

For more information about relationships visit .

For more information about the tags and the library you use access .

    
20.11.2018 / 20:49