mirror of
https://github.com/Hopiu/django-uuslug.git
synced 2026-03-17 04:20:23 +00:00
refactor
This commit is contained in:
parent
a9d7ec1b83
commit
eb40096ebf
4 changed files with 143 additions and 76 deletions
11
README
11
README
|
|
@ -39,7 +39,7 @@ B. Test & contribute to django-uuslug: (for developers)
|
|||
|
||||
Unicode Test Example
|
||||
=====================
|
||||
from uuslug import uuslug as slugify
|
||||
from uuslug import slugify
|
||||
|
||||
s = "This is a test ---"
|
||||
r = slugify(s)
|
||||
|
|
@ -63,7 +63,7 @@ Uniqueness Test Example
|
|||
Override your object's save method with something like this (models.py)
|
||||
|
||||
from django.db import models
|
||||
from uuslug import uuslug as slugify
|
||||
from uuslug import uuslug
|
||||
|
||||
class CoolSlug(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
|
|
@ -73,9 +73,14 @@ class CoolSlug(models.Model):
|
|||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.slug = slugify(self.name, instance=self)
|
||||
self.slug = uuslug(self.name, instance=self)
|
||||
super(CoolSlug, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
You can specify the start number, e.g.: the second slug should start with "-2" instead of "-1":
|
||||
self.slug = uuslug(self.name, instance=self, start_no=2)
|
||||
|
||||
|
||||
Test:
|
||||
=====
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ pkg_resources.require("Unidecode")
|
|||
from unidecode import unidecode
|
||||
|
||||
# only allow the import of our public APIs (UU-SLUG = Uniqure & Unicode Slug)
|
||||
__all__ = ['uuslug']
|
||||
__all__ = ['slugify', 'uuslug']
|
||||
|
||||
|
||||
# character entity reference
|
||||
|
|
@ -34,46 +34,10 @@ REPLACE1_REXP = re.compile(r'[\']+')
|
|||
REPLACE2_REXP = re.compile(r'[^-a-z0-9]+')
|
||||
REMOVE_REXP = re.compile('-{2,}')
|
||||
|
||||
|
||||
def uuslug(s, entities=True, decimal=True, hexadecimal=True,
|
||||
instance=None, slug_field='slug', filter_dict=None):
|
||||
"""This method tries a little harder than django's django.template.defaultfilters.slugify.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s : string
|
||||
Explanation
|
||||
entities: boolean, optional
|
||||
Explanation
|
||||
decimal : boolean, optional
|
||||
Explanation
|
||||
hexadecimal : boolean, optional
|
||||
Explanation
|
||||
instance : Model object or None, optional
|
||||
Explanation
|
||||
slug_field : string, optional
|
||||
Explanation
|
||||
filter_dict : dictionary, optional
|
||||
Explanation
|
||||
|
||||
Returns
|
||||
-------
|
||||
slug : string
|
||||
Explanation
|
||||
|
||||
Examples
|
||||
--------
|
||||
Example usage in save method for model:
|
||||
|
||||
import uuslug as slugify
|
||||
self.slug = slugify(self.name, instance=self)
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
From http://www.djangosnippets.org/snippets/369/
|
||||
def slugify(s, entities=True, decimal=True, hexadecimal=True):
|
||||
"""
|
||||
make a slug from the given string
|
||||
"""
|
||||
|
||||
if type(s) != UnicodeType:
|
||||
s = unicode(s, 'utf-8', 'ignore')
|
||||
|
||||
|
|
@ -110,19 +74,62 @@ def uuslug(s, entities=True, decimal=True, hexadecimal=True,
|
|||
#remove redundant -
|
||||
s = REMOVE_REXP.sub('-', s).strip('-')
|
||||
|
||||
slug = s
|
||||
if instance:
|
||||
def get_query():
|
||||
if hasattr(instance, 'objects'):
|
||||
raise Exception("Error: you must pass an instance to uuslug, not a model.")
|
||||
query = instance.__class__.objects.filter(**{slug_field: slug})
|
||||
if filter_dict:
|
||||
query = query.filter(**filter_dict)
|
||||
if instance.pk:
|
||||
query = query.exclude(pk=instance.pk)
|
||||
return query
|
||||
counter = 1
|
||||
while get_query():
|
||||
slug = "%s-%s" % (s, counter)
|
||||
counter += 1
|
||||
return slug
|
||||
return s
|
||||
|
||||
|
||||
def uuslug(s, instance, entities=True, decimal=True, hexadecimal=True,
|
||||
slug_field='slug', filter_dict=None, start_no=1):
|
||||
"""This method tries a little harder than django's django.template.defaultfilters.slugify.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s : string
|
||||
Explanation
|
||||
entities: boolean, optional
|
||||
Explanation
|
||||
decimal : boolean, optional
|
||||
Explanation
|
||||
hexadecimal : boolean, optional
|
||||
Explanation
|
||||
instance : Model object or None, optional
|
||||
Explanation
|
||||
slug_field : string, optional
|
||||
Explanation
|
||||
filter_dict : dictionary, optional
|
||||
Explanation
|
||||
|
||||
Returns
|
||||
-------
|
||||
slug : string
|
||||
Explanation
|
||||
|
||||
Examples
|
||||
--------
|
||||
Example usage in save method for model:
|
||||
|
||||
import uuslug as slugify
|
||||
self.slug = slugify(self.name, instance=self)
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
From http://www.djangosnippets.org/snippets/369/
|
||||
"""
|
||||
if hasattr(instance, 'objects'):
|
||||
raise Exception("Error: you must pass an instance to uuslug, not a model.")
|
||||
|
||||
queryset = instance.__class__.objects.all()#.only("pk", slug_field)
|
||||
if filter_dict:
|
||||
queryset = queryset.filter(**filter_dict)
|
||||
if instance.pk:
|
||||
queryset = queryset.exclude(pk=instance.pk)
|
||||
|
||||
slug1 = slugify(s, entities=entities, decimal=decimal, hexadecimal=hexadecimal)
|
||||
slug2 = slug1
|
||||
|
||||
counter = start_no
|
||||
while queryset.filter(**{slug_field: slug2}).exists():
|
||||
slug2 = "%s-%s" % (slug1, counter)
|
||||
counter += 1
|
||||
|
||||
return slug2
|
||||
|
|
|
|||
|
|
@ -3,17 +3,30 @@ import os
|
|||
# create a database table only in unit test mode
|
||||
if os.environ['DJANGO_SETTINGS_MODULE'] == 'uuslug.testsettings':
|
||||
from django.db import models
|
||||
from uuslug import uuslug as slugify
|
||||
|
||||
from uuslug import uuslug
|
||||
|
||||
|
||||
class CoolSlug(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
slug = models.CharField(max_length=200)
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.slug = slugify(self.name, instance=self)
|
||||
self.slug = uuslug(self.name, instance=self)
|
||||
super(CoolSlug, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class AnotherSlug(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
slug = models.CharField(max_length=200)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.slug = uuslug(self.name, instance=self, start_no=2)
|
||||
super(AnotherSlug, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,19 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
|
||||
"""Unit tests for uslug"""
|
||||
from django.test import TestCase
|
||||
|
||||
from django.db import models, connection
|
||||
from django.template import Context, Template
|
||||
from uuslug.models import CoolSlug
|
||||
from uuslug import uuslug as slugify
|
||||
from django.test import TestCase
|
||||
from django.db import connections, DEFAULT_DB_ALIAS, reset_queries
|
||||
from django.core.signals import request_started
|
||||
|
||||
# http://pypi.python.org/pypi/django-tools/
|
||||
#from django_tools.unittest_utils.print_sql import PrintQueries
|
||||
|
||||
from uuslug.models import CoolSlug, AnotherSlug
|
||||
from uuslug import slugify
|
||||
|
||||
|
||||
class SlugUnicodeTestCase(TestCase):
|
||||
"""Tests for Slug - Unicode"""
|
||||
|
|
@ -25,19 +35,51 @@ class SlugUnicodeTestCase(TestCase):
|
|||
r = slugify(s)
|
||||
self.assertEquals(r, "ying-shi-ma")
|
||||
|
||||
|
||||
|
||||
class SlugUniqueTestCase(TestCase):
|
||||
"""Tests for Slug - Unique"""
|
||||
|
||||
def test_manager(self):
|
||||
name = "john"
|
||||
c = CoolSlug.objects.create(name=name)
|
||||
c.save()
|
||||
self.assertEquals(c.slug, name)
|
||||
|
||||
c1 = CoolSlug.objects.create(name=name)
|
||||
c1.save()
|
||||
self.assertEquals(c1.slug, name+"-1")
|
||||
|
||||
#with PrintQueries("create first john"): # display the SQL queries
|
||||
with self.assertNumQueries(2):
|
||||
# 1. query: SELECT test, if slug 'john' exists
|
||||
# 2. query: INSERT values
|
||||
obj = CoolSlug.objects.create(name=name)
|
||||
self.assertEquals(obj.slug, "john")
|
||||
|
||||
#with PrintQueries("create second john"): # display the SQL queries
|
||||
with self.assertNumQueries(3):
|
||||
# 1. query: SELECT test, if slug 'john' exists
|
||||
# 2. query: SELECT test, if slug 'john-1' exists
|
||||
# 3. query: INSERT values
|
||||
obj = CoolSlug.objects.create(name=name)
|
||||
self.assertEquals(obj.slug, "john-1")
|
||||
|
||||
def test_start_no(self):
|
||||
name = 'Foo Bar'#'C\'est déjà l\'été.'
|
||||
|
||||
#with PrintQueries("create first 'Foo Bar'"): # display the SQL queries
|
||||
with self.assertNumQueries(2):
|
||||
# 1. query: SELECT test, if slug 'foo-bar' exists
|
||||
# 2. query: INSERT values
|
||||
obj = AnotherSlug.objects.create(name=name)
|
||||
self.assertEquals(obj.slug, "foo-bar")
|
||||
|
||||
#with PrintQueries("create second 'Foo Bar'"): # display the SQL queries
|
||||
with self.assertNumQueries(3):
|
||||
# 1. query: SELECT test, if slug 'foo-bar' exists
|
||||
# 2. query: SELECT test, if slug 'foo-bar-2' exists
|
||||
# 3. query: INSERT values
|
||||
obj = AnotherSlug.objects.create(name=name)
|
||||
self.assertEquals(obj.slug, "foo-bar-2")
|
||||
|
||||
#with PrintQueries("create third 'Foo Bar'"): # display the SQL queries
|
||||
with self.assertNumQueries(4):
|
||||
# 1. query: SELECT test, if slug 'foo-bar' exists
|
||||
# 2. query: SELECT test, if slug 'foo-bar-2' exists
|
||||
# 3. query: SELECT test, if slug 'foo-bar-3' exists
|
||||
# 4. query: INSERT values
|
||||
obj = AnotherSlug.objects.create(name=name)
|
||||
self.assertEquals(obj.slug, "foo-bar-3")
|
||||
|
|
|
|||
Loading…
Reference in a new issue