Commits

Andy Mikhailenko committed d0933d7

Fixed issue #3: slug can exceed field length if prepopulating from longer field. (Thanks to Ollie Rutherfurd)

  • Participants
  • Parent commits 1250a6e

Comments (0)

Files changed (6)

 who have submitted patches, reported bugs, added translations and
 generally made django-autoslug better:
 
-* Blake Imsland,
+* Steve Steiner
+* Blake Imsland
+* Ollie Rutherfurd
 * Your Name Here  ;)

File autoslug/__init__.py

 __author__  = 'Andy Mikhailenko'
 __license__ = 'GNU Lesser General Public License (GPL), Version 3'
 __url__     = 'http://bitbucket.org/neithere/django-autoslug/'
-__version__ = '1.1.2'
+__version__ = '1.1.3'

File autoslug/fields.py

 # app
 from autoslug.settings import slugify
 
+
+SLUG_INDEX_SEPARATOR = '-'    # the "-" in "foo-2"
+
 class AutoSlugField(SlugField):
     """
     AutoSlugField is an extended SlugField able to automatically resolve name
         model = instance.__class__
         field_name = self.name
         index = 1
+        if self.max_length < len(slug):
+            slug = slug[:self.max_length]
         orig_slug = slug
+        sep = SLUG_INDEX_SEPARATOR
         # keep changing the slug until it is unique
         while True:
             try:
                     raise model.DoesNotExist
                 # the slug is not unique; change once more
                 index += 1
-                slug = '%s-%d' % (orig_slug, index)
+                # ensure the resulting string is not too long
+                tail_length = len(sep) + len(str(index))
+                combined_length = len(orig_slug) + tail_length
+                if self.max_length < combined_length:
+                    orig_slug = orig_slug[:self.max_length - tail_length]
+                # re-generate the slug
+                slug = '%s%s%d' % (orig_slug, sep, index)
             except model.DoesNotExist:
                 # slug is unique, no model uses it
                 return slug

File autoslug/models.py

Empty file added.

File autoslug/tests.py

+# -*- coding: utf-8 -*-
+#
+#  Copyright (c) 2008—2009 Andy Mikhailenko
+#
+#  This file is part of django-autoslug.
+#
+#  django-autoslug is free software under terms of the GNU Lesser
+#  General Public License version 3 (LGPLv3) as published by the Free
+#  Software Foundation. See the file README for copying conditions.
+#
+
+
+from django.db.models import Model, CharField
+from autoslug.fields import AutoSlugField
+
+
+class Foo(Model):
+    name = CharField(max_length=200)
+    slug = AutoSlugField(populate_from='name', unique=True)
+
+__doc__ = """
+>>> long_name = 'x' * 250
+>>> foo = Foo(name=long_name)
+>>> foo.save()
+>>> len(foo.slug)
+50
+>>> bar = Foo(name=long_name)
+>>> bar.save()
+>>> [len(x.slug) for x in Foo.objects.all()]
+[50, 50]
+"""

File run_tests.py

+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from django.conf import settings
+from django.core.management import call_command
+
+
+settings.configure(
+    INSTALLED_APPS=('autoslug',),
+    DATABASE_ENGINE='sqlite3'
+)
+
+if __name__ == "__main__":
+    call_command('test', 'autoslug')