Search code examples
regexdjangourldjango-urlsslug

slug url won't display url's that don't have hyphens


for some reason I can't view pages which have a slug without a hyphen. For example:

This doesn't work: /example1

This works: /this-way-works

I have tried changing the regular expressions but had no joy. Any help would be appreciated!

urls

urlpatterns = patterns('',
        url(r'^$', views.index, name='index'),
        url(r'^register_profile/$', views.register_profile, name='register_profile'),
        url(r'^update_profile/$', views.update_profile, name='update_profile'),
        url(r'^create_project/$', views.CreateProject.as_view(), name='create_project'),
        url(r'^(?P<username>\w+)/$', views.profile_page, name='user_profile'),
        url(r'^(?P<slug>[-\w]+)/$', views.project_page, name='user_project'), 
        )

project_page view

def project_page(request, slug): 

    context_dict = {}

    username = request.user.username
    user = get_object_or_404(User, username=username)
    context_dict['project_user'] = user

    project = UserProject.objects.get(slug=slug)
    context_dict['project'] = project

    context_dict['project_title'] = project.title



    return render(request, 'howdidu/project.html', context_dict)

models

class UserProject(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=100)
    project_overview = models.CharField(max_length=1000)
    project_picture = models.ImageField(upload_to='project_images', blank=True)
    date_created = models.DateTimeField(auto_now_add=True)
    project_views = models.IntegerField(default=0)
    project_likes = models.IntegerField(default=0)
    project_followers = models.IntegerField(default=0)
    slug = models.SlugField(max_length=100, unique=True) #should this be unique or not?

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

    def __unicode__(self):
        return self.title

template

{% extends 'howdidu/base.html' %}

{% load staticfiles %}

{% block title %}{{ profile_user.userprofile.first_name }}  {{ profile_user.userprofile.second_name }}{% endblock %}

{% block body_block %}

        <h1>{{ profile_user.userprofile.first_name }}'s profile page</h1>
        <img src="{{ profile_user.userprofile.profile_picture.url }}" width = "150" height = "150"  />
        <h2>{{ profile_user.userprofile.first_name }} {{ profile_user.userprofile.second_name }}</h2>
        <h2>{{ profile_user.userprofile.user_country }}</h2>
        {% if projects %}
            <ul>
                {% for project in projects %}
                <li><a href="{% url 'user_project' project.slug %}">{{ project.title }}</a></li> 
                {% endfor %}
          </ul>
        {% else %}
            <strong>There are no projects present.</strong>
        {% endif %}

        {% if user.is_authenticated %}
        {% if profile_user.username == user.username %}
        <p><a href="{% url 'update_profile' %}">Edit profile</a></p>
        <p><a href="{% url 'create_project' %}">Create new project</a></p>
        {% endif %}
        {% endif %}




{% endblock %}

Solution

  • The problem is in you url ordering.

    url(r'^(?P<username>\w+)/$', views.profile_page, name='user_profile'),
    url(r'^(?P<slug>[-\w]+)/$', views.project_page, name='user_project'),
    

    There is no big difference for Django in these urls. Django will go from up to down and find first match. If there is a - in your slug it will map to

    url(r'^(?P<slug>[-\w]+)/$', views.project_page, name='user_project')
    

    as it is the only url that matches -. But if your slug is example1 link will match

    url(r'^(?P<username>\w+)/$', views.profile_page, name='user_profile'),
    

    url as it is closer to the top. What you need to do is to add another 'level' to the urls. For example:

    url(r'^users/(?P<username>\w+)/$', views.profile_page, name='user_profile'),
    url(r'^projects/(?P<slug>[-\w]+)/$', views.project_page, name='user_project'),
    

    Then everything will work fine.

    P. S. Your url doesn't deppend on user so actually any user can see all projects, I think that's not what you need.Think about this for a little bit and ask me if you need any help.