Skip to content

Commit

Permalink
Merge pull request #1 from Cadasta/feature/random-id-model
Browse files Browse the repository at this point in the history
Add RandomIDModel: first real code.  A proud day.
  • Loading branch information
ian-ross committed Nov 30, 2015
2 parents 9f44ab8 + 142edc5 commit 85fad72
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 2 deletions.
2 changes: 0 additions & 2 deletions cadasta/config/settings/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'organizations'
)

MIDDLEWARE_CLASSES = (
Expand Down
26 changes: 26 additions & 0 deletions cadasta/core/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from django.db import models

from .util import random_id, ID_FIELD_LENGTH


class RandomIDModel(models.Model):
id = models.CharField(primary_key=True, max_length=ID_FIELD_LENGTH)

class Meta:
abstract = True

def save(self, *args, **kwargs):
if not self.id:
kwargs['force_insert'] = True

while True:
self.id = random_id()

if not type(self).objects.filter(pk=self.id).exists():
super(RandomIDModel, self).save(*args, **kwargs)
break
else:
continue

else:
super(RandomIDModel, self).save(*args, **kwargs)
Empty file added cadasta/core/tests/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions cadasta/core/tests/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .testcases import AbstractModelTestCase
from ..models import RandomIDModel


class RandomIDModelTest(AbstractModelTestCase):
abstract_model = RandomIDModel

def test_save(self):
instance = self.model()
instance.save()
self.assertIsNotNone(instance.id)
30 changes: 30 additions & 0 deletions cadasta/core/tests/testcases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from django.test import TestCase
from django.db import connection
from django.core.management.color import no_style
from django.db.models.base import ModelBase


class AbstractModelTestCase(TestCase):
def setUp(self):
# Create a dummy model which extends the abstract model
self.model = ModelBase(
'__TestModel__' + self.abstract_model.__name__,
(self.abstract_model,),
{'__module__': self.abstract_model.__module__}
)

# Create the schema for our test model
self._style = no_style()
sql, _ = connection.creation.sql_create_model(self.model, self._style)

self._cursor = connection.cursor()
for statement in sql:
self._cursor.execute(statement)

def tearDown(self):
# Delete the schema for the test model
sql = connection.creation.sql_destroy_model(
self.model, (), self._style
)
for statement in sql:
self._cursor.execute(statement)
19 changes: 19 additions & 0 deletions cadasta/core/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import random
import string


ID_FIELD_LENGTH = 24

alphabet = string.ascii_lowercase + string.digits
for loser in 'l1o0':
i = alphabet.index(loser)
alphabet = alphabet[:i] + alphabet[i+1:]


def byte_to_base32_chr(byte):
return alphabet[byte & 31]


def random_id():
rand_id = [random.randint(0, 0xFF) for i in range(ID_FIELD_LENGTH)]
return ''.join(map(byte_to_base32_chr, rand_id))

0 comments on commit 85fad72

Please sign in to comment.