Reputation: 59
I have two models Post and Category.
models.py
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
content = models.TextField()
posted = models.DateField(db_index=True, auto_now_add=True)
category = models.ForeignKey('blog.Category')
def __unicode__(self):
return '%s' % self.title
class Category(models.Model):
title = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=100, db_index=True)
def __unicode__(self):
return '%s' % self.title
views.py
def post_view(request, slug, slug1):
return render(request, 'post_view.html', {
'post': get_object_or_404(Post, category=slug, slug=slug1)
})
def category_view(request, slug):
category = get_object_or_404(Category, slug=slug)
return render(request, 'cat_view.html', {
'category': category,
'posts': Post.objects.filter()[:5]
})
urls.py
url(r'category/(?P<slug>[-\w]+)/$', views.category_view, name='cat_view'),
url(r'category/(?P<slug>[-\w]+)/(?P<slug1>[-\w]+)/$', views.post_view, name='post_view'),
and finally the templates category.html
{% block content %}
{% if posts %}
<ul>
{% for post in posts %}
<li><a href="{% url 'blog:post_view' slug=post.category slug1=post.slug %}">
{{ post.title }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>There are no post yet in the {{ category.title }} category ! </p>
{% endif %}
{% endblock %}
post.html
{% block content %}
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<small>{{ post.posted }}</small>
{% endblock %}
The error is raised whenever I try to access a specific Post through the links on the category.html
. At first, I thought it was because of the regex in the urls.py
, but it seems to be a problem with the queries and I have been stuck on it for hours. Any help would be great.
UPDATE
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\exception.py" in inner
39. response = get_response(request)
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in
_get_response
187. response = self.process_exception_by_middleware(e, request)
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in
_get_response
185. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\godfather\PycharmProjects\portfolio\blog\views.py" in post_view
25. 'post': get_object_or_404(Post, category=slug, slug=slug1)
File "C:\Python27\lib\site-packages\django\shortcuts.py" in get_object_or_404
85. return queryset.get(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py" in get
376. clone = self.filter(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py" in filter
796. return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\db\models\query.py" in
_filter_or_exclude
814. clone.query.add_q(Q(*args, **kwargs))
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py" in add_q
1227. clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py" in
_add_q
1253. allow_joins=allow_joins, split_subq=split_subq,
File "C:\Python27\lib\site-packages\django\db\models\sql\query.py" in build_filter
1183. condition = lookup_class(lhs, value)
File "C:\Python27\lib\site-packages\django\db\models\lookups.py" in
__init__
19. self.rhs = self.get_prep_lookup()
File "C:\Python27\lib\site-packages\django\db\models\fields\related_lookups.py" in get_prep_lookup
100. self.rhs = target_field.get_prep_value(self.rhs)
File "C:\Python27\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_value
946. return int(value)
Exception Type: ValueError at /category/Computer/python-data-scientists/ Exception Value: invalid literal for int() with base 10: 'Computer'
Upvotes: 0
Views: 1876
Reputation: 12012
In the template you pass the Category as object, not the category slug. Here is what you have to change:
{% url 'blog:post_view' slug=post.category.slug slug1=post.slug %}
I'd go further and rename few things. In your urls.py
change the second url to this:
url(r'category/(?P<category_slug>[-\w]+)/(?P<post_slug>[-\w]+)/$', views.post_view, name='post_view'),
Then adapt the views.py
to reflect the changes:
def post_view(request, category_slug, post_slug):
return render(request, 'post_view.html', {
'post': get_object_or_404(Post, category__slug=category_slug, slug=post_slug)
})
Please pay attention to the double underscore. It's not a typo.
Naming is important, especially for other people reading your code. The concept of having slug and slug1 is not very descriptive. It's better to make it clear which one is category slug and which one is post slug.
If you go with the above changes then you should adapt this line:
{% url 'blog:post_view' category_slug=post.category.slug post_slug=post.slug %}
Upvotes: 1