views:

336

answers:

1
class Story(db.Model):
    title = db.StringProperty(required=True)
    slug = db.StringProperty(required=True)

I'm working with Django's forms on Google App Engine.

I want to automatically generate a slug from a user-submitted title -- and then I want to validate that it exists. The slug doesn't have to be unique, it just has to exist.

Just making the title attribute required will cause a validation error if the title doesn't exist, but if the title is something like ###??? then my slug will be an empty string.

This post suggests using the model's save method, but the save method is called after validation has completed -- so it only works if you're slugifying a field that you know will turn into a valid slug.

I've tried two solutions, but neither one appeals to me, and I'm sure there's a better way to do it.

First

In the title field's clean method I slugified the title and then raised a ValidationError if a valid slug wasn't produced. This works pretty well and it's probably my best option so far.

The problem is I have to slugify the title again in the model's save method in order to generate a value for the slug field. This feels a little dirty.

Seccond

I made my slug field hidden with the widget forms.HiddenInput and then set the slug field's value to a generated slug after receiving the post data and before checking to see if the form is valid.

Unfortunately, when the slug doesn't exist in this scenario an error pops up that looks like this: (Hidden field slug) My custom error message. Django appends the first part (the stuff in parentheses) to my perfectly fine error message.

In order to get around this I sent the form to my template like this: form.as_p().replace("Hidden field slug) ", "")

But, again, this feels a little dirty.

---

Thanks for your help!

+2  A: 

You could use the TransformProperty from aetycoon:

class Story(db.Model):
    title = db.StringProperty(required=True)
    slug = aetycoon.TransformProperty(title, slugify, required=True)
Nick Johnson
But where should I return an error if the slug produced is an empty string? If I implement the TransformProperty and make the slug field hidden and required, I'll still have the problem in my second approach. (thanks for all of your help nick; you really do an excellent job keeping up with everything. it's amazing)
wings
With the TransformProperty, you can take the first approach, set it to required, and it will throw an error if the slug is empty.
Nick Johnson