def __init__(self, *args, **kwargs): super(LocationCodeCategory, self).__init__(*args, **kwargs) self._formats = [ fmt.char_definition for fmt in LocationCodeDefault.objects.all() ] self._separator = LocationCodeDefault.getSegmentSeparator() self._parser = FormatParser(self._formats, self._separator)
def __init__(self, *args, **kwargs): super(LocationCodeCategory, self).__init__(*args, **kwargs) self._formats = [fmt.char_definition for fmt in LocationCodeDefault.objects.all()] self._separator = LocationCodeDefault.getSegmentSeparator() self._parser = FormatParser(self._formats, self._separator)
class LocationCodeCategory(Base): parent = models.ForeignKey("self", blank=True, null=True, default=0, related_name='children') segment = models.CharField( max_length=248, db_index=True, help_text=_("See the LocationCodeDefault.description for the " + "format used.")) path = models.CharField(max_length=248, editable=False) char_definition = models.ForeignKey(LocationCodeDefault, editable=False) def __init__(self, *args, **kwargs): super(LocationCodeCategory, self).__init__(*args, **kwargs) self._formats = [fmt.char_definition for fmt in LocationCodeDefault.objects.all()] self._separator = LocationCodeDefault.getSegmentSeparator() self._parser = FormatParser(self._formats, self._separator) def _getCategoryPath(self, current=True): parents = LocationCodeCategory.getParents(self) if current: parents.append(self) return self._separator.join([parent.segment for parent in parents]) @classmethod def getParents(self, category): parents = LocationCodeCategory._recurseParents(category) parents.reverse() return parents @classmethod def _recurseParents(self, category): parents = [] if category.parent_id: parents.append(category.parent) more = LocationCodeCategory._recurseParents(category.parent) parents.extend(more) return parents def _levelProducer(self): path = self._getCategoryPath() return path.count(self._separator) _levelProducer.short_description = _("Level") def _parentsProducer(self): return self._getCategoryPath(current=False) _parentsProducer.short_description = _("Segment Parents") def _charDefProducer(self): return self.char_definition.char_definition _charDefProducer.short_description = _("Character Definition") def clean(self): parents = LocationCodeCategory.getParents(self) if self.segment in [parent.segment for parent in parents]: raise ValidationError(_("You cannot save a category in itself.")) if self._separator and self._separator in self.segment: msg = "A segment cannot contain the segment delimiter '%s'." raise ValidationError(_(msg % self._separator)) maxNumSegments = LocationCodeDefault.getMaxNumSegments() length = len(parents) + 1 if length > maxNumSegments: msg = "There are too many segments in this location code, " + \ "found: %s, allowed: %s" raise ValidationError(_(msg % (length, maxNumSegments))) try: self.char_definition = \ LocationCodeDefault.getCharDefinitionBySegment( self._parser.getFormat(self.segment)) except ValueError, e: msg = "Segment does not match a Location Code Default, %s" raise ValidationError(msg % e) if not self.char_definition: msg = "Invalid segment must conform to one of the following " + \ "character definitions: %s" raise ValidationError(_(msg % ', '.join(self._formats)))
class LocationCodeCategory(Base): parent = models.ForeignKey("self", blank=True, null=True, default=0, related_name='children') segment = models.CharField( max_length=248, db_index=True, help_text=_("See the LocationCodeDefault.description for the " + "format used.")) path = models.CharField(max_length=248, editable=False) char_definition = models.ForeignKey(LocationCodeDefault, editable=False) def __init__(self, *args, **kwargs): super(LocationCodeCategory, self).__init__(*args, **kwargs) self._formats = [ fmt.char_definition for fmt in LocationCodeDefault.objects.all() ] self._separator = LocationCodeDefault.getSegmentSeparator() self._parser = FormatParser(self._formats, self._separator) def _getCategoryPath(self, current=True): parents = LocationCodeCategory.getParents(self) if current: parents.append(self) return self._separator.join([parent.segment for parent in parents]) @classmethod def getParents(self, category): parents = LocationCodeCategory._recurseParents(category) parents.reverse() return parents @classmethod def _recurseParents(self, category): parents = [] if category.parent_id: parents.append(category.parent) more = LocationCodeCategory._recurseParents(category.parent) parents.extend(more) return parents def _levelProducer(self): path = self._getCategoryPath() return path.count(self._separator) _levelProducer.short_description = _("Level") def _parentsProducer(self): return self._getCategoryPath(current=False) _parentsProducer.short_description = _("Segment Parents") def _charDefProducer(self): return self.char_definition.char_definition _charDefProducer.short_description = _("Character Definition") def clean(self): parents = LocationCodeCategory.getParents(self) if self.segment in [parent.segment for parent in parents]: raise ValidationError(_("You cannot save a category in itself.")) if self._separator and self._separator in self.segment: msg = "A segment cannot contain the segment delimiter '%s'." raise ValidationError(_(msg % self._separator)) maxNumSegments = LocationCodeDefault.getMaxNumSegments() length = len(parents) + 1 if length > maxNumSegments: msg = "There are too many segments in this location code, " + \ "found: %s, allowed: %s" raise ValidationError(_(msg % (length, maxNumSegments))) try: self.char_definition = \ LocationCodeDefault.getCharDefinitionBySegment( self._parser.getFormat(self.segment)) except ValueError as e: msg = "Segment does not match a Location Code Default, %s" raise ValidationError(msg % e) if not self.char_definition: msg = "Invalid segment must conform to one of the following " + \ "character definitions: %s" raise ValidationError(_(msg % ', '.join(self._formats))) def save(self, *args, **kwargs): # Run all the validators. self.full_clean() # Fix our self. self.path = self._getCategoryPath() super(LocationCodeCategory, self).save(*args, **kwargs) # Fix all the children if any. iterator = self.children.iterator() try: while True: child = iterator.next() child.save() except StopIteration: pass @classmethod def getAllRootTrees(self, segment): result = [] records = LocationCodeCategory.objects.filter(segment=segment) if len(records) > 0: result[:] = [ LocationCodeCategory.getParents(record) for record in records ] return result ## @classmethod ## def getSegmentLength(self, segment=None): ## result = 0 ## record = LocationCodeCategory.objects.get(segment=segment) ## if record: ## #return self.segment_length def __str__(self): return self.path class Meta: verbose_name = _("Location Code") verbose_name_plural = _("Location Codes") ordering = ('path', )