summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/south/creator/freezer.py
diff options
context:
space:
mode:
authorttt2017-05-13 00:29:47 +0530
committerttt2017-05-13 00:29:47 +0530
commitabf599be33b383a6a5baf9493093b2126a622ac8 (patch)
tree4c5ab6e0d935d5e65fabcf0258e4a00dd20a5afa /lib/python2.7/site-packages/south/creator/freezer.py
downloadSBHS-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.py192
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