def __new__(cls, name, bases, attrs): # TODO: Think of a better test to avoid processing Metadata parent class if bases == (object,): return type.__new__(cls, name, bases, attrs) # Save options as a dict for now (we will be editing them) # TODO: Is this necessary, should we bother relaying Django Meta options? Meta = attrs.pop('Meta', {}) if Meta: Meta = Meta.__dict__.copy() # Remove our options from Meta, so Django won't complain help_text = attrs.pop('HelpText', {}) # TODO: Is this necessary if help_text: help_text = help_text.__dict__.copy() options = Options(Meta, help_text) # Collect and sort our elements elements = [(key, attrs.pop(key)) for key, obj in attrs.items() if isinstance(obj, MetadataField)] elements.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) elements = OrderedDict(elements) # Validation: # TODO: Write a test framework for seo.Metadata validation # Check that no group names clash with element names for key, members in options.groups.items(): assert key not in elements, "Group name '%s' clashes with field name" % key for member in members: assert member in elements, "Group member '%s' is not a valid field" % member # Check that the names of the elements are not going to clash with a model field for key in elements: assert key not in RESERVED_FIELD_NAMES, "Field name '%s' is not allowed" % key # Preprocessing complete, here is the new class new_class = type.__new__(cls, name, bases, attrs) options.metadata = new_class new_class._meta = options # Some useful attributes options._update_from_name(name) options._register_elements(elements) try: for backend_name in options.backends: new_class._meta._add_backend(backend_registry[backend_name]) for backend_name in options.backends: backend_registry[backend_name].validate(options) except KeyError: raise Exception('Metadata backend "%s" is not installed.' % backend_name) registry[name] = new_class return new_class
def __new__(cls, name, bases, attrs): # TODO: Think of a better test to avoid processing Metadata parent class if bases == (object, ): return type.__new__(cls, name, bases, attrs) # Save options as a dict for now (we will be editing them) # TODO: Is this necessary, should we bother relaying Django Meta options? Meta = attrs.pop('Meta', {}) if Meta: Meta = Meta.__dict__.copy() # Remove our options from Meta, so Django won't complain help_text = attrs.pop('HelpText', {}) # TODO: Is this necessary if help_text: help_text = help_text.__dict__.copy() options = Options(Meta, help_text) # Collect and sort our elements elements = [(key, attrs.pop(key)) for key, obj in attrs.items() if isinstance(obj, MetadataField)] elements.sort( lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) elements = OrderedDict(elements) # Validation: # TODO: Write a test framework for seo.Metadata validation # Check that no group names clash with element names for key, members in options.groups.items(): assert key not in elements, "Group name '%s' clashes with field name" % key for member in members: assert member in elements, "Group member '%s' is not a valid field" % member # Check that the names of the elements are not going to clash with a model field for key in elements: assert key not in RESERVED_FIELD_NAMES, "Field name '%s' is not allowed" % key # Preprocessing complete, here is the new class new_class = type.__new__(cls, name, bases, attrs) options.metadata = new_class new_class._meta = options # Some useful attributes options._update_from_name(name) options._register_elements(elements) try: for backend_name in options.backends: new_class._meta._add_backend(backend_registry[backend_name]) for backend_name in options.backends: backend_registry[backend_name].validate(options) except KeyError: raise Exception('Metadata backend "%s" is not installed.' % backend_name) registry[name] = new_class return new_class