Adarsh TS
Adarsh TS

Reputation: 303

Changing id field to slug field in django

Everything worked fine when I used <int:pk> in urlconfig to view DetailView page of my blogs.

# included from urls.py in main dir
urlpatterns = [
    path('', views.index, name='blog_index'),
    path('blogs', views.allblogs.as_view(), name='blogs'),
    path('blogs/<int:pk>', views.blogDetail.as_view(), name='blog-detail'),
]
# result url example 127.0.0.1:8000/blog/blogs/2

I later changed my mind to display the url as 127.0.0.1:8000/blogs/new-blog instead of an int value. To achieve this result I made the following changes to urls.py,

urlpatterns = [
    path('', views.index, name='blog_index'),
    path('blogs', views.allblogs.as_view(), name='blogs'),
    re_path(r'^blogs/(?P<slug_me>[-\w]+)$', views.blogDetail.as_view(), name='blog-detail'),
]

and following additions to models.py:

class Blog(models.Model):
    ...

    slug = models.SlugField(default=slugify('iamslug'+str(id)))

    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.title)
        super(Blog, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('blog-detail', kwargs={'slug':self.slug, 'id':self.id})

But now when I access 127.0.0.1:8000/blog/blogs, it throws the following error:

Reverse for 'blog-detail' with keyword arguments '{'slug': 'djangodbmodelsfieldscharfield', 'id': 1}' not found. 1 pattern(s) tried: ['blog\\/blogs/(?P<slug_me>[-\\w]+)$']

And at 127.0.0.1:8000/blog/blogs/new-blog, it throws this error:

Generic detail view blogDetail must be called with either an object pk or a slug in the URLconf.

I am unable to move forward. I tried changing urls.py to include slug keyword, which results in Page Not Found.

# changed re_path(r'^blogs/(?P<slug_me>[-\w]+)$', views.blogDetail.as_view(), name='blog-detail') to
re_path(r'^blogs/(?P<slug>[-\w]+)$', views.blogDetail.as_view(), name='blog-detail')

Upvotes: 0

Views: 1257

Answers (1)

Gabriel Usen
Gabriel Usen

Reputation: 44

Try this in your urls.py

urlpatterns = [
    path('', views.index, name='blog_index'),
    path('blogs', views.allblogs.as_view(), name='blogs'),
    path('blogs/<slug:slug>/', views.blogDetail.as_view(), name='blog-detail'),

your models.py is suppose to look like this

class Blog(models.Model):
...

slug = models.SlugField()

def save(self, *args, **kwargs):
    if not self.slug:
        self.slug = slugify(self.title)
    return super().save(*args, **kwargs)

def get_absolute_url(self):
    return reverse('blog-detail', kwargs={'slug':self.slug})

Use slugfield strictly and check out django doc for urls pathing

Upvotes: 2

Related Questions