ryan
ryan

Reputation: 645

Slugfield URL implementation in Django

So, I am having some difficulty trying to slugify a title field in my model and still have it return the proper information.

Currently, a user can follow the url, if the list in their account exists under this regular expression:

url(r'^user/(?P<username>\w+)/list/(?P<listname>\w+)/$', mylistpage, name='lists'),

The issue I face is that the user can have a list containing spaces, but the regex bases their url off their list name. I am wanting to implement a slug url, but still have it retrieve the correct model/object information.

I am trying to have a slug field and then pre-populate it based on the list name, but I am lost at how this implementation is supposed to work. Much appreciation in advance from any insight.

Model

class newlist(models.Model):


    user = models.ForeignKey(User)
    list_name = models.CharField(max_length = 100,)
    picture = models.ImageField(upload_to='profiles/', default = "/media/profiles/default.jpg")
    slugurl = models.SlugField(default = slugurl(self))

    def __str__(self):
        return self.list_name

    def slugurl(self):
        return slugify(self.list_name)

Views

def mylistpage(request, username, listname):

    context = RequestContext(request)

    #make sure that the user is authenticated
    if username == request.user.username:
        #If the user is authenticated, then perform the following functions to the page
        if request.user.is_authenticated():
            #Store the current user request object into a variable
            user = User.objects.get(username=username)

            #Store the list name to the item that starts with the url input
            listname = request.user.newlist_set.filter(list_name__iexact=listname)

            listitems = request.user.newlist_set.all()
            if not listname:
                return redirect('/notfound')
    else:
        return redirect('/notfound')

    return render_to_response('listview.html', {'lista': listname}, context)

Upvotes: 1

Views: 1065

Answers (1)

Sebastian Wozny
Sebastian Wozny

Reputation: 17506

I have used django-autoslug to great success. You can find a live example here.

SlugField is just a char field with a little syntactic sugar.

You will want to name your slug just slug so django can find it automatically in the URL resolution and passes the right parameter to views.

Your amended code would look like:

from autoslug import AutoSlugField
from django.db import models

class Newlist(models.Model): # Classes start with uppercase names by default
    user = models.ForeignKey(User)
    list_name = models.CharField(max_length = 100,)
    picture = models.ImageField(upload_to='profiles/', default = "/media/profiles/default.jpg")
    slug = AutoSlugField(populate_from='list_name')
    def __str__(self):
        return self.list_name

Your View:

def mylistpage(request,username, slug):

    context = RequestContext(request)

    #make sure that the user is authenticated
    if username == request.user.username:
        #If the user is authenticated, then perform the following functions to the page
        if request.user.is_authenticated():
            #Store the current user request object into a variable
            user = User.objects.get(username=username)

            #Store the list name to the item that starts with the url input
            listname = request.user.newlist_set.filter(slug=slug)

            listitems = request.user.newlist_set.all()
            if not listname:
                return redirect('/notfound')
    else:
        return redirect('/notfound')

    return render_to_response('listview.html', {'lista': listname}, context)

urls.py

url(r'^user/(?P<username>\w+)/list/(?P<slug>[\w-]+)/$', mylistpage, name='lists'),

Upvotes: 2

Related Questions