diff options
author | ttt | 2017-05-13 00:29:47 +0530 |
---|---|---|
committer | ttt | 2017-05-13 00:29:47 +0530 |
commit | abf599be33b383a6a5baf9493093b2126a622ac8 (patch) | |
tree | 4c5ab6e0d935d5e65fabcf0258e4a00dd20a5afa /lib/python2.7/site-packages/south/creator/freezer.py | |
download | SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.gz SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.tar.bz2 SBHS-2018-Rpi-abf599be33b383a6a5baf9493093b2126a622ac8.zip |
added all server files
Diffstat (limited to 'lib/python2.7/site-packages/south/creator/freezer.py')
-rw-r--r-- | lib/python2.7/site-packages/south/creator/freezer.py | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/south/creator/freezer.py b/lib/python2.7/site-packages/south/creator/freezer.py new file mode 100644 index 0000000..0f98cea --- /dev/null +++ b/lib/python2.7/site-packages/south/creator/freezer.py @@ -0,0 +1,192 @@ +""" +Handles freezing of models into FakeORMs. +""" + +from __future__ import print_function + +import sys + +from django.db import models +from django.db.models.base import ModelBase, Model +from django.contrib.contenttypes.generic import GenericRelation + +from south.utils import get_attribute, auto_through +from south import modelsinspector +from south.utils.py3 import string_types + +def freeze_apps(apps): + """ + Takes a list of app labels, and returns a string of their frozen form. + """ + if isinstance(apps, string_types): + apps = [apps] + frozen_models = set() + # For each app, add in all its models + for app in apps: + for model in models.get_models(models.get_app(app)): + # Only add if it's not abstract or proxy + if not model._meta.abstract and not getattr(model._meta, "proxy", False): + frozen_models.add(model) + # Now, add all the dependencies + for model in list(frozen_models): + frozen_models.update(model_dependencies(model)) + # Serialise! + model_defs = {} + model_classes = {} + for model in frozen_models: + model_defs[model_key(model)] = prep_for_freeze(model) + model_classes[model_key(model)] = model + # Check for any custom fields that failed to freeze. + missing_fields = False + for key, fields in model_defs.items(): + for field_name, value in fields.items(): + if value is None: + missing_fields = True + model_class = model_classes[key] + field_class = model_class._meta.get_field_by_name(field_name)[0] + print(" ! Cannot freeze field '%s.%s'" % (key, field_name)) + print(" ! (this field has class %s.%s)" % (field_class.__class__.__module__, field_class.__class__.__name__)) + if missing_fields: + print("") + print(" ! South cannot introspect some fields; this is probably because they are custom") + print(" ! fields. If they worked in 0.6 or below, this is because we have removed the") + print(" ! models parser (it often broke things).") + print(" ! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork") + sys.exit(1) + + return model_defs + +def freeze_apps_to_string(apps): + return pprint_frozen_models(freeze_apps(apps)) + +### + +def model_key(model): + "For a given model, return 'appname.modelname'." + return "%s.%s" % (model._meta.app_label, model._meta.object_name.lower()) + +def prep_for_freeze(model): + """ + Takes a model and returns the ready-to-serialise dict (all you need + to do is just pretty-print it). + """ + fields = modelsinspector.get_model_fields(model, m2m=True) + # Remove useless attributes (like 'choices') + for name, field in fields.items(): + fields[name] = remove_useless_attributes(field) + # See if there's a Meta + fields['Meta'] = remove_useless_meta(modelsinspector.get_model_meta(model)) + # Add in our own special items to track the object name and managed + fields['Meta']['object_name'] = model._meta.object_name # Special: not eval'able. + if not getattr(model._meta, "managed", True): + fields['Meta']['managed'] = repr(model._meta.managed) + return fields + +### Dependency resolvers + +def model_dependencies(model, checked_models=None): + """ + Returns a set of models this one depends on to be defined; things like + OneToOneFields as ID, ForeignKeys everywhere, etc. + """ + depends = set() + checked_models = checked_models or set() + # Get deps for each field + for field in model._meta.fields + model._meta.many_to_many: + depends.update(field_dependencies(field, checked_models)) + # Add in any non-abstract bases + for base in model.__bases__: + if issubclass(base, models.Model) and hasattr(base, '_meta') and not base._meta.abstract: + depends.add(base) + # Now recurse + new_to_check = depends - checked_models + while new_to_check: + checked_model = new_to_check.pop() + if checked_model == model or checked_model in checked_models: + continue + checked_models.add(checked_model) + deps = model_dependencies(checked_model, checked_models) + # Loop through dependencies... + for dep in deps: + # If the new dep is not already checked, add to the queue + if (dep not in depends) and (dep not in new_to_check) and (dep not in checked_models): + new_to_check.add(dep) + depends.add(dep) + return depends + +def field_dependencies(field, checked_models=None): + checked_models = checked_models or set() + depends = set() + arg_defs, kwarg_defs = modelsinspector.matching_details(field) + for attrname, options in arg_defs + list(kwarg_defs.values()): + if options.get("ignore_if_auto_through", False) and auto_through(field): + continue + if options.get("is_value", False): + value = attrname + elif attrname == 'rel.through' and hasattr(getattr(field, 'rel', None), 'through_model'): + # Hack for django 1.1 and below, where the through model is stored + # in rel.through_model while rel.through stores only the model name. + value = field.rel.through_model + else: + try: + value = get_attribute(field, attrname) + except AttributeError: + if options.get("ignore_missing", False): + continue + raise + if isinstance(value, Model): + value = value.__class__ + if not isinstance(value, ModelBase): + continue + if getattr(value._meta, "proxy", False): + value = value._meta.proxy_for_model + if value in checked_models: + continue + checked_models.add(value) + depends.add(value) + depends.update(model_dependencies(value, checked_models)) + + return depends + +### Prettyprinters + +def pprint_frozen_models(models): + return "{\n %s\n }" % ",\n ".join([ + "%r: %s" % (name, pprint_fields(fields)) + for name, fields in sorted(models.items()) + ]) + +def pprint_fields(fields): + return "{\n %s\n }" % ",\n ".join([ + "%r: %r" % (name, defn) + for name, defn in sorted(fields.items()) + ]) + +### Output sanitisers + +USELESS_KEYWORDS = ["choices", "help_text", "verbose_name"] +USELESS_DB_KEYWORDS = ["related_name", "default", "blank"] # Important for ORM, not for DB. +INDEX_KEYWORDS = ["db_index"] + +def remove_useless_attributes(field, db=False, indexes=False): + "Removes useless (for database) attributes from the field's defn." + # Work out what to remove, and remove it. + keywords = USELESS_KEYWORDS[:] + if db: + keywords += USELESS_DB_KEYWORDS[:] + if indexes: + keywords += INDEX_KEYWORDS[:] + if field: + for name in keywords: + if name in field[2]: + del field[2][name] + return field + +USELESS_META = ["verbose_name", "verbose_name_plural"] +def remove_useless_meta(meta): + "Removes useless (for database) attributes from the table's meta." + if meta: + for name in USELESS_META: + if name in meta: + del meta[name] + return meta |