Django Slugfield removing articles ('the', 'a', 'an', 'that')

Question:

I’m using django 1.10 and I have this setup:

class Chapter(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(unique=True)
    date_completed = models.DateTimeField(blank=True, null=True)

    completed = models.BooleanField(default=False)

    def __str__(self):
        return self.title

In the admin, I have :

class ChapterAdmin (admin.ModelAdmin):

    list_display = ('title','slug', 'date_completed',)
    list_filter = ['title', 'date_completed']
    prepopulated_fields = {"slug": ("title",)}

I noticed that when I create a chapter with a title like “A boy and the pig”, I get “boy-and-pig” as the slug. Django is stripping of the articles from my slug. Why is this so and what’s the way around it?

Asked By: segunolalive

||

Answers:

Why is this so?

Well, that’s the default behaviour of the Slugfield, in Django. Why is it like that? Because generally, it’s been considered better for SEO.

(I say considered, as the article linked mentions this might be dated thinking. The premise is that articles and the like are usually considered Stop Words, the most common words in a language; they’re so common that they are unhelpful for a search engine to index, as they feature in most, if not all titles. )

What’s the Way Around It?

Firstly – why do you want to get around it? What’s the use case?

But if you’re satisified you really want to do it, then it’s quite simple:

from django.template.defaultfilters import slugify
would_be_slug = 'This is one of those rarest of things: A blog that uses article.'
slugify(would_be_slug)
>>>u'this-is-one-of-those-rarest-of-things-a-blog-that-uses-article'

This answer has some great advice on overriding standard fields and slugfields.

There’s also a nice package that will do this for you if you don’t want to roll your own.

Answered By: Withnail

You can write your own logic to filter specific words and articles out:

List of Stop Words:
Check out this blog post about SEO and stop words. At the end of the page, you’ll find a list containing over hundreds of stop words.

Implementation:

    def save(self, *args, **kwargs):  # new

      if not self.slug:
          # remove articles
          words_to_remove = ["the", "a", "an", "that", "this"] # etc.
          filtered_title = ""

          for word in self.title.split():
              if word not in words_to_remove:
                  filtered_title = filtered_title + " " + ''.join(str(word))
          # to keep uniqueness, combine the id with the title
          self.slug = slugify(str(self.pk) + "-" + filtered_title)
      return super().save(*args, **kwargs)
Answered By: alexrogo
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.