FieldError - Related Field got invalid lookup: iexact

Hi there! I am a newbie to Django and I created a simple blog while watching a tutorial with Codemy.com

The video playlist was out-of-date (of course) and I have been working on making the site my own. During the tutorial, I created a bunch of sample posts and in turn there were blog categories created. I have since deleted all the sample posts however, I noticed the categories did not delete themselves. I, perhaps mistakenly, went into the admin and manually deleted the categories. I then created another post with the category of “Coding”. The text displays properly and the link lights up when I need it to.

However, now whenever I want to navigate to my category page by clicking on the link to Coding on my blog post I am presented with an error screen. The link should have simply shown me every post with the coding category. In this case, it should just be one post.

I’ve gone back a few commits and I’m still encountering the issue.

The error screen:

The line it has an issue with is here:
views.py:

# cats is the name of the variable containing the string used in the urls.py file and this must match.
> def CategoryView(request, cats):
>     category_posts = Post.objects.filter(category__iexact=cats.title().replace('-', ' '))
>     return render(request, 'categories.html', {'cats':cats.title().replace('-', ' '), 'category_posts':category_posts})

models.py:

> class Category(models.Model):
>     name = models.CharField(max_length=255)
>     class Meta:
>         verbose_name_plural = "Categories"
> 
>     def __str__(self):
>         return self.name
> 
>     def get_absolute_url(self):
>         return reverse('home')
> 
> class Post(models.Model):
>     title = models.CharField(max_length=255)
>     header_image = models.ImageField(null=True, blank=True, upload_to="images/")
>     title_tag = models.CharField(max_length=255)
>     author = models.ForeignKey(User, on_delete=models.CASCADE)
>     body = RichTextField(blank=True, null=True)
>     post_date = models.DateField(auto_now_add=True)
>     category= models.ForeignKey(Category, max_length=60, on_delete=models.CASCADE, related_name="cats")
>     snippet = models.CharField(max_length=255)
>     likes = models.ManyToManyField(User, related_name='blog_posts')
> 
>     def total_likes(self):
>         return self.likes.count()
> 
>     def __str__(self):
>         return self.title + ' | ' + str(self.author)
> 
>     def get_absolute_url(self):
>         return reverse('home')

My suspicion is I need to nuke my database and think of a better way to delete unused categories. I attempted to check out the iexact queryset to understand the function better and the FieldError page to no avail.

I’m hoping this is detailed enough but, please let me know if I should also post up my html code as well. I figured this was a problem with the views.py and the models.py more so than html.

This isn’t a data problem, it is a code issue.

In your view, you have:
category_posts = Post.objects.filter(category__iexact=cats.title().replace('-', ' '))

Then, your definition of the Post model contains:
category= models.ForeignKey(Category, max_length=60, on_delete=models.CASCADE, related_name="cats")

So, the problem is with your filter.

Post.object.filter(category...)
category is a reference to the Model, not a field within the model. You’re trying to perform a string comparison (iexact) against the model. However, I believe what you’re really trying to match here is the name field within the Category model, which means your filter should be:
Post.object.filter(category__name__iexact=...

Oh my goodness. This is exactly the issue and I thank you so much for your help! I saw the use of the “name” part in a few other similar posts but, I had no idea about where to put it. But yes, I had to change the category field to a Foreignkey and also to change the name in the db to Categories instead of Categorys. During that change, I should have added “name” as you suggested. Again, thanks!