djangosearchdjango-querysetdjango-q

Search with Django (for Tags)


I'm doing a 3-part search. (1st username 2.caption 3.tag) only the 3rdtag search doesn't work. (The error I get when I add the tag
-Related Field got invalid lookup: icontains)

I also tried using the Tag model, but it didn't work, can you help?

enter code here

myviews.py

@login_required(login_url="login")
def UserSearch(request):
    query = request.GET.get("q")
    context = {}
    specailAd= Ad.objects.order_by('-dateAd')
        
    ads = list(Ad.objects.all())
    oneAd = random.choice(ads)
    post_items = Post.objects.all().order_by('-posted')     
    if query:
        post_items = post_items.filter(caption__icontains = query)

    if query:
        post_items = post_items.filter(tags__icontains = query)
        
    if query:
        users = User.objects.filter(Q(username__icontains=query))

        #Pagination
        paginator = Paginator(users, 6)
        page_number = request.GET.get('page')
        users_paginator = paginator.get_page(page_number)

        context = {
                'users': users_paginator,
                'post_items':post_items,
                'specailAd':specailAd,
                'oneAd':oneAd,
            }
        
    template = loader.get_template('direct/search_user.html')

mymodels.py

class Post(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    content =  models.ManyToManyField(PostFileContent, related_name='contents')
    caption = models.TextField(max_length=1500, verbose_name='Caption')
    posted = models.DateTimeField(auto_now_add=True)
    tags = models.ManyToManyField(Tag, related_name='tags')
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    likes = models.ManyToManyField(
        User, related_name='like', default=None, blank=True)
    like_count = models.BigIntegerField(default='0')


    def get_absolute_url(self):
        return reverse('postdetails', args=[str(self.id)])

    def __str__(self):
        return str(self.id)

class Tag(models.Model):
    title = models.CharField(max_length=75, verbose_name='Tag')
    slug = models.SlugField(null=False, unique=True)

    class Meta:
        verbose_name='Tag'
        verbose_name_plural = 'Tags'

    def get_absolute_url(self):
        return reverse('tags', args=[self.slug])
        
    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        return super().save(*args, **kwargs)

Solution

  • You can't use icontains with a m2m relationship, you should instead use another double underscore to the value that you want to check has icontains, e.g. name or another field:

    post_items = post_items.filter(tags__name__icontains=query)
    

    As an aside, your three if-statements are all doing the same thing so you might as well combine them together.