ValueError at /category/economy/: Field 'id' expected a number but got 'economy'

I try to add new path and this happen "Field 'id' expected a number but got 'economy'."

in traceback the highlighted line is in the file which i mentioned below.

category_posts = Post.objects.filter(category=cats)

I am sharing my files plz help me to get rid of the issue.

urlpatterns = [
    path('search',, name="search"),
    path('contact/',, name="contact"),
    path('success/', views.successView, name="success"),
    path('category/<str:cats>/', views.CategoryView, name ="category"),
] + static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)

here i used str:cats, yet it shows "Field 'id' expected a number but got 'economy'."

def CategoryView(request, cats):   # here cats is same which mentioned in dynamic url.
    category_posts = Post.objects.filter(category=cats)
    return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})

"category_posts = Post.objects.filter(category=cats)" this line of code shows in traceback

from django.db import models

class Category(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
    title = models.CharField(max_length=255, verbose_name="Title")
    parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE, blank=
    True, null=True)

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"
        ordering = ['title']

    def __str__(self):
        return self.title

class Post(models.Model):
    title = models.CharField(max_length=100)
    public_date = models.DateField(null=True)
    public_time = models.TimeField(null=True,default="")
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="Category", null=True)
    image = models.ImageField(upload_to='images/',null=True, blank=True)
    body = models.TextField()

    class Meta:
        verbose_name = "Post"
        verbose_name_plural = "Posts"
        ordering = ['public_date']

    def summary(self):
        return self.body[:100]

    def pub_date(self):
        return self.public_date.strftime('%b %e,%y')
    # to give layout for time and date

    def __str__(self):
        return self.title


{% extends 'base.html' %}

{%block content%}

<h1> Category: {{ cats }} </h1>

{% for post in category_posts %}

<div class="container mt-3">
    <div class="row mb-2">
        <div class="col-md-6">
          <div class="card flex-md-row mb-4 box-shadow h-md-250">
            <div class="card-body d-flex flex-column align-items-start">
              <strong class="d-inline-block mb-2 text-primary">{{ post.category }}</strong>
              <h3 class="mb-0">
                <a class="text-dark" href="{% url 'detail' %}">{{post.title}}</a>
              <div class="mb-1 text-muted">{{ post.public_date }}</div>
              <p class="card-text mb-auto">{{ post.summary }}</p>
              <a href="{% url 'detail' %}">Continue reading</a>
            <img class="card-img-right flex-auto d-none d-md-block" data-src="holder.js/200x250?theme=thumb" alt="Thumbnail [200x250]" style="width: 200px; height: 250px;" src="data:image/svg+xml;charset=UTF-8," data-holder-rendered="true">


{% endfor %}

{% else %}
    <h2>Sorry this page does not exist....</h2>
{% endif %}


I am confused it demands. can someone help me to solve it plz.

Its because you are querying it wrong: So instaed of doing this:


def CategoryView(request, cats):   # here cats is same which mentioned in dynamic url.
    category_posts = Post.objects.filter(category=cats)
    return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})

Try something with this query. I'm supposing you want to query all the posts of a specific category that will be coming from your URL.

from django.shortcuts import get_object_or_404

def CategoryView(request, cats):
    # method 1
    category_posts = Post.objects.filter(category__title=cats)
    # method 2
    category = Category.objects.get(title=cats)
    category_posts = category.Category.all() # here .Category is the related_name you used in your Post model
    # method 3:
    category = get_object_or_404(Category, title=cats) # will raise 404 if no category found with the given title
    category_posts = category.Category.all()
    return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})

PS: When you don't know what your ForeignKey related_name should be. Then go for the plural name of the model. Like in the current case:


category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name="posts", null=True)

This way we can query like this category_posts = category.posts.all()

Back to Top