how to replace pk with slug in detailview

Viewed 159

how to make slug place pk?

views.py

from django.shortcuts import render
from django.views.generic import ListView, DetailView

from .models import Category,Subcategory, Product, Characteristic

class CategoryView(ListView):
    """list of categories"""
    model = Category


class CategoryDetailView(DetailView):
    """Full description of categories"""
    model = Category

models.py

class Category(models.Model):
    name_category = models.CharField(verbose_name = 'name category', max_length = 100, null=True)
    image = models.ImageField(null=True, blank=True, upload_to="media/", verbose_name='pic')

    def __str__(self):
        return self.name_category


class Subcategory(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, verbose_name='category', related_name='sub')
    name_subcategory = models.CharField(verbose_name = 'name subcategory', max_length = 100, null=True)
    image = models.ImageField(null=True, blank=True, upload_to="media/", verbose_name='pic')
    url = models.SlugField(max_length=160, unique=True, null=True)

    def __str__(self):
        return self.name_subcategory

urls.py

urlpatterns = [
    path("", views.CategoryView.as_view()),
    path('<int:pk>/', views.CategoryDetailView.as_view(), name='category_detail'),
    ]

in the link template I form like this

{% for category in category_list %}
<a href="{% url 'category_detail' pk=category.pk %}">{{category.name_category}}</a>
<img src="{{category.image.url}}" width="100px" height="100px">
   {% for img in category.sub.all %}
      {{ img.name_subcategory }}
   {% endfor %}
{% endfor %}

Now my links are formed like this http://127.0.0.1:8000/1/ how to make the place pk in the link substituted slug from the Subcategory model

1 Answers

In your model, you need a SlugField. It might be easy to make use of an AutoSlugField [readthedocs] the django-autoslug package [readthedocs]:

from autoslug import AutoSlugField

class Category(models.Model):
    name_category = models.CharField(
        verbose_name='name category',
        max_length=100,
        null=True
    )
    image = models.ImageField(
        null=True,
        blank=True,
        upload_to='media/',
        verbose_name='pic'
    )
    slug = AutoSlugField(populate_from='name_category')

    def __str__(self):
        return self.name_category

In the url patterns you make use of a parameter named slug:

urlpatterns = [
    path('', views.CategoryView.as_view()),
    path('<slug:slug>/', views.CategoryDetailView.as_view(), name='category_detail'),
]

In the templates you then use the slug field instead of the primary key:

{% for category in category_list %}
    <a href="{% url 'category_detail' slug=category.slug %}">{{category.name_category}}</a>
    <img src="{{category.image.url}}" width="100px" height="100px">
    {% for img in category.sub.all %}
        {{ img.name_subcategory }}
    {% endfor %}
{% endfor %}
Related