views:

365

answers:

1

Django has a unique_for_date property you can set when adding a SlugField to your model. This causes the slug to be unique only for the Date of the field you specify:

class Example(models.Model):
    title = models.CharField()
    slug = models.SlugField(unique_for_date='publish')
    publish = models.DateTimeField()

What would be the best way to achieve the same kind of functionality for a non-DateTime field like a ForeignKey? Ideally, I want to do something like this:

class Example(models.Model):
    title = models.CharField()
    slug = models.SlugField(unique_for='category')
    category = models.ForeignKey(Category)

This way I could create the following urls:

/example/category-one/slug
/example/category-two/slug
/example/category-two/slug <--Rejected as duplicate

My ideas so far:

  • Add a unique index for the slug and categoryid to the table. This requires code outside of Django. And would the built-in admin handle this correctly when the insert/update fails?

  • Override the save for the model and add my own validation, throwing an error if a duplicate exists. I know this will work but it doesn't seem very DRY.

  • Create a new slug field inheriting from the base and add the unique_for functionality there. This seems like the best way but I looked through the core's unique_for_date code and it didn't seem very intuitive to extend it.

Any ideas, suggestions or opinions on the best way to do this?

+4  A: 

What about unique_together?

class Example(models.Model):
    title = models.CharField()
    slug = models.SlugField(db_index=False)
    category = models.ForeignKey(Category)

    class Meta:
        unique_together = (('slug','category'),)
        # or also working since Django 1.0:
        # unique_together = ('slug','category',)

This creates an index, but it is not outside of Django ;) Or did I miss the point?

Felix Kling
Of course, it's as simple as that. Thanks for the help and updating the answer!
Lance McNearney