2014-01-27 3 views
2

Я пытаюсь создать дружественные URL-адреса SEO, где все пробелы заменены дефисом.Использование Slugify в URL-адресах Django

Это, как я 'slugifying' URL-адрес с помощью slugify в Django шаблоны

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

Вот мой urls.py

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

Это мой взгляд

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} 

Теперь %20 в URL-адресах изменился на -, но я получаю ошибку DJ matching query does not exist.

Также это игнорирует & в имени ди-джея. Например, он изменяет адрес для DJ Above & Beyond на www.example.com/top100/above-beyond

ответ

3

Вы пытаетесь запросить объект с его slug вместо его имени в базе данных. Slug - это строка, вычисленная из исходного имени, которое вы можете использовать в URL-адресе (потому что это SEO-friendly). Но вы не можете запрашивать с ним объекты, если вы не сохранили этот пул в любой точке вашей базы данных. В самом деле, невозможно получить исходное имя из пули.

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

Вы должны использовать SlugField() и получить объект хотел в соответствии с этой новой области. Краткий пример:

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) 

На практике, вы можете использовать templatetags slugify, если вы хотите использовать чистый URL, как StackOverflow: они используют идентификатор вопроса для извлечения содержимого из URL, но есть также название, которое вы можете изменить, оно все равно перенаправит вас.

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

+1 правильный ответ и хорошее форматирование – Thomas

+0

@Maxime - Хорошее объяснение, я должен сказать. У меня есть сомнения. Получая новостной объект из модели, например 'news = get_object_or_404 (News, slug = slug)', не требуется ли запрашивать поле 'slug', занимает много времени? Я имею в виду, что он не индексирован, и даже если мы его индексируем, писать запросы будут тяжелыми. Разве это не так? Поправьте меня если я ошибаюсь. – PythonEnthusiast

+0

@PythonEnthusiast Если я правильно помню свои курсы последипломного обучения в DB, ​​индексирующие строки используют хэши в индексе B-дерева. Таким образом, он добавляет относительно небольшую стоимость вычисления хэша по сравнению с целыми числами. Однако, если вы не указали индекс в поле 'slug', это действительно медленнее, чем запрос первичного ключа, когда ваша таблица получает (десятки?) Тысяч записей. Но это еще одна проблема, которую вы должны знать, когда ваша база данных начинает становиться больше, чем случайный блог с менее чем 100 статьями. –

0

Почему вы не используете SlugField() в своих моделях? Затем вы можете задать запрос на свой слизень. Я предполагаю, что ошибка возникает из запроса на имя вместо slug.

Смежные вопросы