Abdul
Abdul

Reputation: 3

I Want View where a list of posts under a Category displays alone

am working on a simple news website using Django. My issue is that, i want to be able to have posts under a certain category listed under it in one view when a user clicks on a category (e.g Sports)... i made two classes in my models and they are:

class Category(models.Model):
POLITICS = 'Politics'
SPORTS = 'Sports'
ENTERTAINMENT = 'Entertainment'
TECHNOLOGY = 'Technology'

CHOICE_CATEGORY_TYPE = (
        (POLITICS, 'Politics'),
        (SPORTS, 'Sports'),
        (ENTERTAINMENT, 'Entertainment'),
        (TECHNOLOGY, 'Technology'),

    )

category_type = models.CharField(max_length=50, choices=CHOICE_CATEGORY_TYPE, default=None)

def __str__(self):
    return self.category_type



   class Post(models.Model):
       category_type = models.ForeignKey(Category, on_delete=models.CASCADE)
       title = models.CharField(max_length=100)
       author = models.CharField(max_length=100)
       pub_date = models.DateField()
       photo = models.ImageField()
       body = models.TextField()


   def __str__(self):
        return self.title

Secondly, here are my views:

def index(request):
posts = Post.objects.all()
return render(request, 'blog/index.html', {'posts': posts})

def detail(request, pk):
    article = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/detail.html', {'article': article})

def categories(request, category_type=None):
    category_post = get_object_or_404(Category, category_type=category_type)
    post_list = Post.objects.all()
    return render(request, 'blog/category.html', {'category_post': 
category_post, 'post_list': post_list})

Lastly my urls:

from django.conf.urls import url
from . import views

app_name = 'blog'

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.detail, name='detail'),
    url(r'^categories/(?P<category_type>[0-9]+)/$', views.categories, 
name='categories'),
]

lastly, this is the error i get when i try create a hyperlink in a Category name to lead me to that category page to get a list of posts under it, from my index page.

Reverse for 'categories' with arguments '(<Category: Sports>,)' not found. 1 
pattern(s) tried: ['blog/categories/(?P<category_type>[0-9]+)/$']
Request Method: GET
Request URL:    http://127.0.0.1:8000/blog/
Django Version: 1.11.5
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'categories' with arguments '(<Category: Sports>,)' not found. 1 
pattern(s) tried: ['blog/categories/(?P<category_type>[0-9]+)/$']
Exception Location: C:\Users\Abdul-Waris\Desktop\website\venv\lib\site-
packages\django\urls\resolvers.py in _reverse_with_prefix, line 497
Python Executable:  C:\Users\Abdul-
Waris\Desktop\website\venv\Scripts\python.exe
Python Version: 3.6.2
Python Path:    
['C:\\Users\\Abdul-Waris\\Desktop\\website\\mysite',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv\\Scripts\\python36.zip',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv\\DLLs',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv\\lib',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv\\Scripts',
 'c:\\users\\abdul-waris\\appdata\\local\\programs\\python\\python36\\Lib',
 'c:\\users\\abdul-waris\\appdata\\local\\programs\\python\\python36\\DLLs',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv',
 'C:\\Users\\Abdul-Waris\\Desktop\\website\\venv\\lib\\site-packages']
Server time:    Fri, 29 Sep 2017 22:23:48 +0000

Thank you

Upvotes: 0

Views: 71

Answers (1)

Zach King
Zach King

Reputation: 1208

The first line of your error says

Reverse for 'categories' with arguments '(<Category: Sports>,)' not found.

If you look at your urls.py you defined the url for the category page like so: url(r'^categories/(?P<category_type>[0-9]+)/$', views.categories, name='categories')

The regular expression you used for the endpoint accepts 1 or more digits 0-9. So it would match a URL like /categories/3 or /categories/2632301, but not letters such as "sports." I would recommend changing the regular expression to accept 1 or more alphanumerics. Also, since this is the URL for viewing a single category, I wouldn't name the URL "categories" but maybe something like "category" or "one_category":

url(r'^categories/(?P<category_type>[a-zA-Z0-9]+)/$', views.categories, name='category')

Now your URL will match correctly for URLs such as /categories/sports, /categories/entertainment and /categories/SpoRts123

Also, in, say your blog/detail.html template, you can create a URL dynamically to the post's category like so: {% url 'category' category_type=article.category_type %}

My final suggestion is that you make your foreign key to category a ManyToManyField instead; think about, you can have one category with many posts, and one post could have many categories. This depends on your context and is completely up to you, but I'd suggest using Many-to-Many since later down the road you might decide you'd like to attach more than one category to a post/article.

Upvotes: 1

Related Questions