Search code examples
pythondjangoslug

Slug in Django URL


I need your help. I working on my own project. And I need show single news from news list.I do next steps:

in model:

 class Notice(models.Model):
     notice_header = models.CharField(max_length=150, verbose_name="Notice header", blank=False)
     notice_content = RichTextField(verbose_name="Notice content")
     notice_publish_date = models.DateField(verbose_name="Publish date", default=date.today)
     notice_slug = models.CharField(max_length=50, verbose_name="Notice URL", blank=False, default="#", unique=True)
     #SEO Data
     seo_page_title = models.CharField(max_length=150, verbose_name="SEO Page Title", blank=True)
     seo_page_description = models.TextField(verbose_name="SEO Page Description", blank=True)
     seo_page_keywords = models.TextField(verbose_name="SEO Keywords", blank=True)

     class Meta:
         verbose_name = "Notice"
         verbose_name_plural = "Notice list"

     def __str__(self):
         return self.notice_header

     def __unicode__(self):
         return self.notice_header

In view:

from django.shortcuts import render_to_response as rtp
from models import *

def notice_list(request):
    notice_articles = Notice.objects.order_by("-id")
    context = {"NOTICE_LIST": notice_articles}
    return rtp("notice.html", context)


def single_notice(request, alias):
    current_news = Notice.objects.get(notice_slug=alias)
    context = {"NOTICE_SINGLE": current_news}
    return rtp("notice_single.html", context)

in urls:

url(r'notice/', notice_list), 
url(r'notice/(?P<alias>[^/]+)', single_notice),

in notice.html

{

% for notice in NOTICE_LIST %}
                <div class="uk-width-1-2@l uk-width-1-2@m">
                    <a href="{{ notice.notice_slug }}">
                        {{ notice.notice_header }}
                    </a>
                </div>
                <div class="uk-width-1-2@l uk-width-1-2@m uk-visible@m"><p>{{ notice.notice_publish_date }}</p></div>
                <hr class="uk-width-1-1@l">
            {% endfor %}

I see notice list on the page. But, when I try to select single notice for reading, page reloads and single_notice function doesn't work.

notice_slug in database contains chars and numbers.

What I doing wrong?

best regards, Alex


Solution

  • Here :

    <a href="{{ notice.notice_slug }}">
    

    This is not the url, it's only the slug part of it. Also as Alasdair rightly mentions, your "notice_list" url regexp don't end with a "$" so it will also match "notice/" hence your page reloading (where you would get a 404 instead with the proper regexp)

    What wou want is first to name your urls (makes life easier, really):

    urls = [
        url(r'^notice/$', notice_list, name="notice_list"), 
        url(r'^notice/(?P<alias>[^/]+)$', single_notice, name="single_notice"),
        # etc
        ]
    

    Then in your template use the {% url %} tag:

    <a href="{% url 'single_notice' alias=notice.notice_slug %}">whatever/<a>
    

    NB: also I'm not quite sure your regexp for the 'single_notice' url is ok but that's another question.