Skip to content

Commit

Permalink
Using exception for constraint handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
gregmuellegger committed Feb 28, 2010
1 parent ffabc2d commit 6164b24
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
19 changes: 8 additions & 11 deletions src/django_autofixture/autofixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ class CreateInstanceError(Exception):
pass


class InvalidConstraint(Exception):
pass


class AutoFixture(object):
'''
We don't support the following fields yet:
Expand Down Expand Up @@ -76,9 +72,9 @@ def __init__(self, model,
``constraints``: A list of callables. The constraints are used to
verify if the created model instance may be used. The callable
gets the actual model as first and the instance as second
parameter. The instance is not saved yet at that moment.
It may return ``None`` to indicate that everything is ok or a
list of field names that are not passing the constraint.
parameter. The instance is not populated yet at this moment.
The callable may raise an ``InvalidConstraint`` exception to
indicate which fields violate the constraint.
``follow_fk``: A boolean value indicating if foreign keys should be
set to random, already existing, instances of the related
Expand Down Expand Up @@ -260,13 +256,14 @@ def process_m2m(self, instance, field):

def check_constrains(self, instance):
'''
Return field names which need recalculation.
Return fieldnames which need recalculation.
'''
recalc_fields = []
for constraint in self.constraints:
fields = constraint(self.model, instance)
if fields:
recalc_fields.extend(fields)
try:
constraint(self.model, instance)
except constraints.InvalidConstraint, e:
recalc_fields.extend(e.fields)
return recalc_fields

def create_one(self, commit=True):
Expand Down
19 changes: 16 additions & 3 deletions src/django_autofixture/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,35 @@
from django.db.models import fields


class InvalidConstraint(Exception):
def __init__(self, fields, *args, **kwargs):
self.fields = fields
super(InvalidConstraint, self).__init__(*args, **kwargs)


def unique_constraint(model, instance):
error_fields = []
for field in instance._meta.fields:
if field.unique:
check = {field.name: getattr(instance, field.name)}
unique = not bool(model._default_manager.filter(**check))
if not unique:
return (field,)
error_fields.append(field)
if error_fields:
raise InvalidConstraint(error_fields)


def unique_together_constraint(model, instance):
error_fields = []
if instance._meta.unique_together:
for unique_fields in instance._meta.unique_together:
check = {}
for field_name in unique_fields:
check[field_name] = getattr(instance, field_name)
unique = not bool(model._default_manager.filter(**check))
if not unique:
return [instance._meta.get_field_by_name(field_name)[0]
for field_name in unique_fields]
error_fields.extend(
[instance._meta.get_field_by_name(field_name)[0]
for field_name in unique_fields])
if error_fields:
raise InvalidConstraint(error_fields)

0 comments on commit 6164b24

Please sign in to comment.