Lisek
Lisek

Reputation: 23

Searching with multiple values in django

I want to create simple search in Django. I want to find all objects in which any word from keywords array is in meme.title or meme.author or meme.tags, and user.request is meme.user.

from django.db import models
from django.conf import settings

User = settings.AUTH_USER_MODEL

class Meme(models.Model):
    user = models.ForeignKey(User, on_delete='CASCADE')
    title = models.CharField(max_length=100)
    description = models.TextField(null=True,
                         blank=True, max_length=1000)
    author = models.CharField(max_length=100)
    page_link = models.TextField(blank=True, max_length=500)
    img_link = models.TextField(max_length=1000)
    tags = models.CharField(max_length=100)

    def __str__(self):
        return self.title

For example if I have keywords = ['funny', 'old', 'black_humor'] and current user is XYZ I want to find all memes that have that meme.user field is XYZ and title, author or tags contains any word from keywords.

Upvotes: 2

Views: 3236

Answers (1)

Ben Boyer
Ben Boyer

Reputation: 1234

What you need is a Q Object. By default if you use filter and chain severall argument it will use a AND logic. For more complex query like chained AND, you need to use Q. So your queryset should look like:

from django.db.models import Q
#get the current_user
current_user = request.user
keywords=  ['funny', 'old', 'black_humor']
qs = [Q(title__icontains=keyword)|Q(author__icontains=keyword)|Q(tags__icontains=keyword) for keyword in keywords]

query = qs.pop() #get the first element

for q in qs:
    query |= q
filtered_user_meme = Meme.objects.filter(query, user=current_user)

More info on Q obects : https://docs.djangoproject.com/en/2.2/topics/db/queries/#complex-lookups-with-q-objects

Upvotes: 2

Related Questions