13

I want to generate a random slug for my model, but without setting "blank=True" (as I want to enforce it later with validation.)

I was wondering if I could do something like this:

slug = models.SlugField(unique=True, default=some_method(), verbose_name='URL Slug')

Where some_method is a method which generates a random slug? I've tried the above code and it doesn't work :(

What I'd like to do is generate a unique slug (unique_slugify?)

Hanpan
  • 10,013
  • 25
  • 77
  • 115

5 Answers5

27

You can use this when you want your slug to be generated automatically with the entry made in some other field in the same model, where the slug lies.

from django_extensions.db.fields import AutoSlugField

slug = AutoSlugField(_('slug'), max_length=50, unique=True, populate_from=('name',))
  • populate_from is the field in the model which will auto generate the slug
avramov
  • 2,119
  • 2
  • 18
  • 41
Prateek
  • 1,538
  • 13
  • 22
  • 5
    For those that don't know, it appears the django_extensions module is from the library of the same name: http://packages.python.org/django-extensions/# – MrOodles Apr 19 '12 at 21:47
10

You could override the models save-method so that when a new entity is created, you generate the slug on the fly. Something like:

if not self.pk:
    self.slug = ''.join(random.sample(string.ascii_lowercase, 10))

You could do that, but it isn't very good and better would be to let the slug be a deterministic slugified version of the objects name.

Björn Lindqvist
  • 19,221
  • 20
  • 87
  • 122
  • I don't mind if that is the case, I am just confused as to how I'd set it to that as the default. I am not using the admin panel – Hanpan Feb 03 '11 at 10:04
  • a random string is not good for uniqueness, better to stick with something like digest of (timestamp in combination with random) – Tommaso Barbugli Feb 03 '11 at 10:06
  • Thanks. I didn't want to overwrite the save method but it seems it is unavoidable. Tommaso, if you have an example of what you mean I'd appreciate it. – Hanpan Feb 03 '11 at 10:29
5

default has to be a value or a callable.
So it's default=some_method, not default=some_method(). Here is an example:

from django.contrib.auth.models import UserManager

def randomString():
    um = UserManager()
    return( um.make_random_password( length=25 ) )

class Foo( models.Model ):
    code = models.CharField( max_length=25, default=randomString )
wchargin
  • 15,589
  • 12
  • 71
  • 110
BigJ
  • 51
  • 1
  • 2
1

maybe model validation can help? http://docs.djangoproject.com/en/dev/ref/models/instances/

You can just simple validate the value which should be written in a slug field and if it exists already, generate something unique.

Also overriding of the models save method could be the solution.

Cheers.

Ignas Butėnas
  • 6,061
  • 5
  • 32
  • 47
1

searching in google, I found similar question: How to use slug in django

I think so the better approach is rewrite the save method, and validade the field in form.

But, slug should be unique, so generate random string is not good! Like Tommaso Bardugi say early, if you add the timestamp in url, this is resolved.

Community
  • 1
  • 1
Tarsis Azevedo
  • 1,463
  • 14
  • 21