Skip to content
Snippets Groups Projects
Commit 240c37a2 authored by Martin Burchell's avatar Martin Burchell
Browse files

Merge branch 'multiple_taxonomies' into add_multiple_terms_api

parents efb72e65 5402eb41
No related branches found
No related tags found
2 merge requests!46Tagging frontend,!45Add multiple terms api
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('taxonomies', '0003_taxonomy_multiplicity'),
]
operations = [
migrations.AddField(
model_name='taxonomy',
name='vocabulary',
field=models.CharField(default=b'closed', max_length=30, choices=[(b'fixed', 'Not modifiable by any user, system only'), (b'closed', 'Only admin users who have permission to define and edit taxonomies'), (b'open', 'Any user who has permission to use taxonomies')]),
),
]
...@@ -31,6 +31,8 @@ class Taxonomy(models.Model): ...@@ -31,6 +31,8 @@ class Taxonomy(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
# To do Categories, you use 'optional' and 'closed',
# to do free tagging use 'multiple' and 'open'
multiplicity = models.CharField( multiplicity = models.CharField(
choices=( choices=(
('optional', _('Zero or One')), ('optional', _('Zero or One')),
...@@ -40,26 +42,25 @@ class Taxonomy(models.Model): ...@@ -40,26 +42,25 @@ class Taxonomy(models.Model):
max_length=30, max_length=30,
) )
# My thoughts on how this grows... vocabulary = models.CharField(
# choices=(
# ('fixed', _('Not modifiable by any user, system only')),
# vocabulary = models.CharField( ('closed', _('Only admin users who have permission to define and edit taxonomies')),
# ... ('open', _('Any user who has permission to use taxonomies')),
# choices=( ),
# ('fixed', _('Not modifiable by any user, system only')), default='closed',
# ('closed', _('Only admin users who have permission to define and edit taxonomies')), max_length=30,
# ('open', _('Any user who has permission to use taxonomies')), )
# )
# )
# To do Categories, you use 'optional' and 'closed', @property
# to do free tagging use 'multiple' and 'open' def is_open(self):
return self.vocabulary == 'open'
class TermManager(models.Manager): class TermManager(models.Manager):
def by_taxonomy(self, taxonomy, name): def by_taxonomy(self, taxonomy, name):
""" Fetch an existing Term by its name and its """ Fetch a Term by its name and its
Taxonomy slug which, together should be unique together. Taxonomy slug which, together should be unique together.
args: args:
...@@ -72,21 +73,30 @@ class TermManager(models.Manager): ...@@ -72,21 +73,30 @@ class TermManager(models.Manager):
The term object with the given name in the given Taxonomy. The term object with the given name in the given Taxonomy.
throws: throws:
DoesNotExist if no Term matches the given combination DoesNotExist if Taxonomy with the given slug does not exist
DoesNotExist if named Term does not exist, unless the Taxonomy
vocabulary is open - in this case the Term will be created
ValueError if taxonomy is not one of the allowed types ValueError if taxonomy is not one of the allowed types
""" """
if isinstance(taxonomy, basestring): if isinstance(taxonomy, basestring):
taxonomy_slug = taxonomy taxonomy = Taxonomy.objects.get(slug=taxonomy)
elif isinstance(taxonomy, Taxonomy): elif not isinstance(taxonomy, Taxonomy):
taxonomy_slug = taxonomy.slug
else:
raise ValueError( raise ValueError(
"taxonomy must be a Taxonomy instance " "taxonomy must be a Taxonomy instance "
"or a valid taxonomy slug") "or a valid taxonomy slug")
return self.select_related('taxonomy').get(
taxonomy__slug=taxonomy_slug, if taxonomy.is_open:
name=name term, _ = self.select_related('taxonomy').get_or_create(
) taxonomy=taxonomy,
name=name
)
else:
term = self.select_related('taxonomy').get(
taxonomy=taxonomy,
name=name
)
return term
class Term(models.Model): class Term(models.Model):
......
...@@ -50,3 +50,24 @@ def test_is_optional_false_for_multiplicity_multiple(): ...@@ -50,3 +50,24 @@ def test_is_optional_false_for_multiplicity_multiple():
taxonomy = TaxonomyFactory(multiplicity='multiple') taxonomy = TaxonomyFactory(multiplicity='multiple')
assert not taxonomy.is_optional assert not taxonomy.is_optional
@pytest.mark.django_db
def test_is_open_true_for_vocabulary_open():
taxonomy = TaxonomyFactory(vocabulary='open')
assert taxonomy.is_open
@pytest.mark.django_db
def test_is_open_false_for_vocabulary_fixed():
taxonomy = TaxonomyFactory(vocabulary='fixed')
assert not taxonomy.is_open
@pytest.mark.django_db
def test_is_open_false_for_vocabulary_closed():
taxonomy = TaxonomyFactory(vocabulary='closed')
assert not taxonomy.is_open
...@@ -35,3 +35,29 @@ def test_term_by_taxonomy_with_taxonomies_with_taxonomy(term_with_context): ...@@ -35,3 +35,29 @@ def test_term_by_taxonomy_with_taxonomies_with_taxonomy(term_with_context):
assert term.name == term_with_context.name assert term.name == term_with_context.name
assert term.taxonomy == term_with_context.taxonomy assert term.taxonomy == term_with_context.taxonomy
@pytest.mark.django_db
def test_unknown_term_by_taxonomy_creates_term_if_open():
taxonomy = TaxonomyFactory(vocabulary='open')
term = Term.objects.by_taxonomy(
taxonomy=taxonomy,
name="a term that doesn't exist",
)
assert term.name == "a term that doesn't exist"
assert term.taxonomy == taxonomy
@pytest.mark.django_db
def test_unknown_term_by_taxonomy_throws_exception_if_not_open():
taxonomy = TaxonomyFactory(vocabulary='closed')
with pytest.raises(Term.DoesNotExist) as excinfo:
Term.objects.by_taxonomy(
taxonomy=taxonomy,
name="a term that doesn't exist",
)
assert excinfo.value.message == "Term matching query does not exist."
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment