Reputation: 645
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.
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)
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
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