rant_category() got an unexpected keyword argument 'slug'
Question:
Running into an rant_category() got an unexpected keyword argument 'slug'
on my django project. Basically, I just need to get the slug of the #category
in my app to show it in the url.
Here’s my code:
views.py
class RantListView(ListView):
model = Rant
context_object_name = "rants"
template_name = "rants/rant_list.html"
class RantDetailView(DetailView):
model = Rant
template_name = "rants/rant_detail.html"
def rant_category(request, category):
rants = Rant.objects.filter(categories__slug__contains=category)
context = {"category": category, "rants": rants}
return render(request, "rants/rant_category.html", context)
models.py
class Category(models.Model):
title = models.CharField(max_length=50)
slug = AutoSlugField(populate_from="title", slugify_function=to_slugify)
class Meta:
get_latest_by = "-date_added"
verbose_name = _("Category")
verbose_name_plural = _("Categories")
def get_absolute_url(self):
return reverse("rants:rant-category", kwargs={"slug": self.slug})
def __str__(self):
return self.slug
class Rant(BaseModel, models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.TextField(blank=False)
slug = AutoSlugField(populate_from="post", slugify_function=to_slugify)
categories = models.ManyToManyField(Category, related_name="rants")
class Meta:
get_latest_by = "-date_added"
verbose_name = _("rant")
verbose_name_plural = _("rants")
def get_absolute_url(self):
return reverse("rants:rant-detail", kwargs={"slug": self.slug})
def __str__(self):
return self.slug
html code
{% for rant in rants %}
{{ rant.post }}
{% for category in rant.categories.all %}
<a href="{% url 'rants:rant-category' category.slug %}">#{{ category.title }}</a>
{% endfor %}
{% endfor %}
I’m getting an:
TypeError at /rants/category/category 1/
rant_category() got an unexpected keyword argument 'slug'
haven’t coded in awhile so I based everything on my old tutorial https://github.com/reyesvicente/cookiecutter-blog-tutorial-learnetto but it seems to not be working.
EDIT
Here’s my urls.py
on the app:
path("", RantListView.as_view(), name="rant"),
path("<str:slug>/", RantDetailView.as_view(), name="rant-detail"),
path("category/<str:slug>/", rant_category, name="rant-category"),
Answers:
It should be slug
in rant_category
view not category
, like so:
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
context = {"category": slug, "rants": rants}
return render(request, "rants/rant_category.html", context)
Figured it out with the help of @sunderam dubey
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
context = {"slug": slug, "rants": rants}
return render(request, "rants/rant_category.html", context)
{% for rant in rants %}
{{rant.title}}
{% for category in rant.categories.all %}
{{category.title}}
{% endfor %}
{% endfor %}
Now I have this data:
To explain the issue …
def rant_category(request, category):
category
here is actually the category slug from the url.
path("category/<str:slug>/", rant_category, name="rant-category"),
So the view function is getting slug
but only has a parameter called category
. As the previous answer notes you need to change the function parameters for the view to reference slug
instead. Then if you specifically need to reference the category object itself in the template you need to get that object first and pass that in the context, rather than the slug. So ..
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
category = Category.objects.get(slug=slug)
context = {"category": category, "rants": rants}
return render(request, "rants/rant_category.html", context)
Hope this gives a little explanation as to why it was wrong and the different options you have to fix it.
Running into an rant_category() got an unexpected keyword argument 'slug'
on my django project. Basically, I just need to get the slug of the #category
in my app to show it in the url.
Here’s my code:
views.py
class RantListView(ListView):
model = Rant
context_object_name = "rants"
template_name = "rants/rant_list.html"
class RantDetailView(DetailView):
model = Rant
template_name = "rants/rant_detail.html"
def rant_category(request, category):
rants = Rant.objects.filter(categories__slug__contains=category)
context = {"category": category, "rants": rants}
return render(request, "rants/rant_category.html", context)
models.py
class Category(models.Model):
title = models.CharField(max_length=50)
slug = AutoSlugField(populate_from="title", slugify_function=to_slugify)
class Meta:
get_latest_by = "-date_added"
verbose_name = _("Category")
verbose_name_plural = _("Categories")
def get_absolute_url(self):
return reverse("rants:rant-category", kwargs={"slug": self.slug})
def __str__(self):
return self.slug
class Rant(BaseModel, models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.TextField(blank=False)
slug = AutoSlugField(populate_from="post", slugify_function=to_slugify)
categories = models.ManyToManyField(Category, related_name="rants")
class Meta:
get_latest_by = "-date_added"
verbose_name = _("rant")
verbose_name_plural = _("rants")
def get_absolute_url(self):
return reverse("rants:rant-detail", kwargs={"slug": self.slug})
def __str__(self):
return self.slug
html code
{% for rant in rants %}
{{ rant.post }}
{% for category in rant.categories.all %}
<a href="{% url 'rants:rant-category' category.slug %}">#{{ category.title }}</a>
{% endfor %}
{% endfor %}
I’m getting an:
TypeError at /rants/category/category 1/
rant_category() got an unexpected keyword argument 'slug'
haven’t coded in awhile so I based everything on my old tutorial https://github.com/reyesvicente/cookiecutter-blog-tutorial-learnetto but it seems to not be working.
EDIT
Here’s my urls.py
on the app:
path("", RantListView.as_view(), name="rant"),
path("<str:slug>/", RantDetailView.as_view(), name="rant-detail"),
path("category/<str:slug>/", rant_category, name="rant-category"),
It should be slug
in rant_category
view not category
, like so:
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
context = {"category": slug, "rants": rants}
return render(request, "rants/rant_category.html", context)
Figured it out with the help of @sunderam dubey
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
context = {"slug": slug, "rants": rants}
return render(request, "rants/rant_category.html", context)
{% for rant in rants %}
{{rant.title}}
{% for category in rant.categories.all %}
{{category.title}}
{% endfor %}
{% endfor %}
Now I have this data:
To explain the issue …
def rant_category(request, category):
category
here is actually the category slug from the url.
path("category/<str:slug>/", rant_category, name="rant-category"),
So the view function is getting slug
but only has a parameter called category
. As the previous answer notes you need to change the function parameters for the view to reference slug
instead. Then if you specifically need to reference the category object itself in the template you need to get that object first and pass that in the context, rather than the slug. So ..
def rant_category(request, slug):
rants = Rant.objects.filter(categories__slug__contains=slug)
category = Category.objects.get(slug=slug)
context = {"category": category, "rants": rants}
return render(request, "rants/rant_category.html", context)
Hope this gives a little explanation as to why it was wrong and the different options you have to fix it.