Question

I'm trying to create SEO friendly urls where all spaces are replaced with a hyphen.

This is how I'm 'slugifying' the URL by using slugify in Django templates

<a href="{% url 'dj' dj_name=dj.name|slugify %}">

Here is my urls.py

url(r'^top100/(?P<dj_name>[a-zA-Z0-9 \'&-]+)/$', views.dj, name='dj')

This is my view

def dj(request, dj_name):
    dj = DJ.objects.get(name=dj_name)
    dj_song_list = Song.objects.filter(artist=dj, duplicate=False).order_by('-votes', '-release_date')
    return render(request, 'hunt/dj.html', {'dj_song_list': dj_song_list, 'dj':dj}

Now the %20 in the urls has changed to a - but I get the error DJ matching query does not exist.

Also this ignores & in the DJ name. For example it changes the url for the DJ Above & Beyond to www.example.com/top100/above-beyond

Était-ce utile?

La solution

You're trying to request an object with its slug instead of its name in database. The slug is a string, compute from the original name, which you can use in URL (because it's SEO-friendly). But you can't request objects with it if you don't have save this slug anywhere in your database. Indeed, it's impossible to retrieve the original name from the slug.

Above & Beyond --> above-beyond --> Above @ Beyond  }
                                --> above & beyond  } A lot of possibilities...
                                --> ABOVE - BEYOND  } 
                                --> ...

You need to use a SlugField() and get the object wanted according to this new field. Short example:

class News(models.Model):
    title = models.CharField('title', max_length=100)
    slug = models.SlugField('slug', max_length=100, unique=True)
    content = models.TextField('news content')

    def get_absolute_url(self):
        return reverse('news-view', args=(self.slug, ))

# In the app/urls.py:
from . import views
urlpatterns = [
    url(r'^(?P<slug>.+)/$', view.news_detail, name='news-view'),
    #...
]

# In the 'news_detail' view (app/views.py)
news = get_object_or_404(News, slug=slug)

In practice, you can use the templatetags slugify if you want to use clean URL like stackoverflow: they're using the ID of the question to retrieve the content from the URL, but there's also the title, which you can change, it'll redirect you anyway.

http://stackoverflow.com/questions/21377984/using-slugify-in-django-urls
                                   ^^^^^^^^
                                   ID used  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                            slug just for SEO purpose, not
                                            used to retrieve from the db

Autres conseils

why don't you use SlugField() in your models ? Then you can queryset on your slug. I guess the error comes from the queryset on name instead of a slug.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top