mirror of
https://github.com/django/django.git
synced 2025-04-22 16:24:40 +00:00
magic-removal: cleanup Options initialisation
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1728 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5907e9337f
commit
743b02825e
@ -18,12 +18,7 @@ import sys
|
||||
if not hasattr(__builtins__, 'set'):
|
||||
from sets import Set as set
|
||||
|
||||
# Calculate the module_name using a poor-man's pluralization.
|
||||
get_module_name = lambda class_name: class_name.lower() + 's'
|
||||
|
||||
# Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
|
||||
get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip()
|
||||
|
||||
attribute_transforms = {}
|
||||
class ModelBase(type):
|
||||
"Metaclass for all models"
|
||||
def __new__(cls, name, bases, attrs):
|
||||
@ -31,69 +26,30 @@ class ModelBase(type):
|
||||
if not bases or bases == (object,):
|
||||
return type.__new__(cls, name, bases, attrs)
|
||||
|
||||
try:
|
||||
meta_attrs = attrs.pop('META').__dict__
|
||||
del meta_attrs['__module__']
|
||||
del meta_attrs['__doc__']
|
||||
except KeyError:
|
||||
meta_attrs = {}
|
||||
|
||||
# Create the class.
|
||||
new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
|
||||
|
||||
opts = Options(
|
||||
module_name = meta_attrs.pop('module_name', get_module_name(name)),
|
||||
# If the verbose_name wasn't given, use the class name,
|
||||
# converted from "InitialCaps" to "lowercase with spaces".
|
||||
verbose_name = meta_attrs.pop('verbose_name', get_verbose_name(name)),
|
||||
verbose_name_plural = meta_attrs.pop('verbose_name_plural', ''),
|
||||
db_table = meta_attrs.pop('db_table', ''),
|
||||
ordering = meta_attrs.pop('ordering', None),
|
||||
unique_together = meta_attrs.pop('unique_together', None),
|
||||
admin = meta_attrs.pop('admin', None),
|
||||
where_constraints = meta_attrs.pop('where_constraints', None),
|
||||
object_name = name,
|
||||
app_label = meta_attrs.pop('app_label', None),
|
||||
exceptions = meta_attrs.pop('exceptions', None),
|
||||
permissions = meta_attrs.pop('permissions', None),
|
||||
get_latest_by = meta_attrs.pop('get_latest_by', None),
|
||||
order_with_respect_to = meta_attrs.pop('order_with_respect_to', None),
|
||||
module_constants = meta_attrs.pop('module_constants', None),
|
||||
)
|
||||
|
||||
if meta_attrs != {}:
|
||||
raise TypeError, "'class META' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())
|
||||
new_class.add_to_class('_meta', opts)
|
||||
|
||||
# Create the DoesNotExist exception.
|
||||
new_class.DoesNotExist = types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {})
|
||||
|
||||
# Figure out the app_label by looking one level up.
|
||||
new_class.add_to_class('_meta',
|
||||
Options(attrs.pop('META', None)))
|
||||
new_class.add_to_class('DoesNotExist',
|
||||
types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {}) )
|
||||
|
||||
#Figure out the app_label by looking one level up.
|
||||
#FIXME: wrong for nested model modules
|
||||
app_package = sys.modules.get(new_class.__module__)
|
||||
app_label = app_package.__name__.replace('.models', '')
|
||||
app_label = app_label[app_label.rfind('.')+1:]
|
||||
|
||||
|
||||
# Cache the app label.
|
||||
opts.app_label = app_label
|
||||
|
||||
new_class._meta.app_label = app_label
|
||||
|
||||
# Add all attributes to the class.
|
||||
for obj_name, obj in attrs.items():
|
||||
new_class.add_to_class(obj_name, obj)
|
||||
|
||||
# Give the class a docstring -- its definition.
|
||||
if new_class.__doc__ is None:
|
||||
new_class.__doc__ = "%s.%s(%s)" % (opts.module_name, name, ", ".join([f.name for f in opts.fields]))
|
||||
|
||||
if hasattr(new_class, 'get_absolute_url'):
|
||||
new_class.get_absolute_url = curry(get_absolute_url, opts, new_class.get_absolute_url)
|
||||
|
||||
opts._prepare()
|
||||
new_class._prepare()
|
||||
|
||||
# Populate the _MODELS member on the module the class is in.
|
||||
app_package.__dict__.setdefault('_MODELS', []).append(new_class)
|
||||
|
||||
return new_class
|
||||
|
||||
def cmp_cls(x, y):
|
||||
@ -152,6 +108,9 @@ class Model(object):
|
||||
dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
|
||||
|
||||
def add_to_class(cls, name, attribute):
|
||||
transform = attribute_transforms.get(name, None)
|
||||
if transform:
|
||||
attribute = transform(attribute)
|
||||
if hasattr(attribute, 'contribute_to_class'):
|
||||
attribute.contribute_to_class(cls, name)
|
||||
else:
|
||||
@ -160,12 +119,21 @@ class Model(object):
|
||||
|
||||
def _prepare(cls):
|
||||
# Creates some methods once self._meta has been populated.
|
||||
if cls._meta.order_with_respect_to:
|
||||
opts = cls._meta
|
||||
opts._prepare()
|
||||
|
||||
if opts.order_with_respect_to:
|
||||
cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
|
||||
cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
|
||||
|
||||
# Give the class a docstring -- its definition.
|
||||
if cls.__doc__ is None:
|
||||
cls.__doc__ = "%s.%s(%s)" % (opts.module_name, cls.__name__, ", ".join([f.name for f in opts.fields]))
|
||||
|
||||
if hasattr(cls, 'get_absolute_url'):
|
||||
cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url)
|
||||
|
||||
dispatcher.send(signal=signals.class_prepared, sender=cls)
|
||||
#RelatedField.do_pending_lookups(cls)
|
||||
|
||||
_prepare = classmethod(_prepare)
|
||||
|
||||
|
@ -7,31 +7,56 @@ from django.db.models.exceptions import FieldDoesNotExist
|
||||
|
||||
from bisect import bisect
|
||||
|
||||
class Options:
|
||||
def __init__(self, module_name='', verbose_name='', verbose_name_plural='', db_table='',
|
||||
ordering=None, unique_together=None, admin=None,
|
||||
where_constraints=None, object_name=None, app_label=None,
|
||||
exceptions=None, permissions=None, get_latest_by=None,
|
||||
order_with_respect_to=None, module_constants=None):
|
||||
# Move many-to-many related fields from self.fields into self.many_to_many.
|
||||
self.fields, self.many_to_many = [], []
|
||||
self.module_name, self.verbose_name = module_name, verbose_name
|
||||
self.verbose_name_plural = verbose_name_plural or verbose_name + 's'
|
||||
self.db_table = db_table
|
||||
self.ordering = ordering or []
|
||||
self.unique_together = unique_together or []
|
||||
self.where_constraints = where_constraints or []
|
||||
self.exceptions = exceptions or []
|
||||
self.permissions = permissions or []
|
||||
self.object_name, self.app_label = object_name, app_label
|
||||
self.get_latest_by = get_latest_by
|
||||
self.order_with_respect_to = order_with_respect_to
|
||||
self.module_constants = module_constants or {}
|
||||
self.admin = admin
|
||||
import re
|
||||
# Calculate the module_name using a poor-man's pluralization.
|
||||
get_module_name = lambda class_name: class_name.lower() + 's'
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
# Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces".
|
||||
get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip()
|
||||
|
||||
|
||||
default_names = ['module_name','verbose_name','verbose_name_plural','db_table','ordering',
|
||||
'unique_together', 'admin','where_constraints', 'exceptions', 'permissions',
|
||||
'get_latest_by','order_with_respect_to', 'module_constants']
|
||||
|
||||
class Options:
|
||||
def __init__(self, meta):
|
||||
self.fields, self.many_to_many = [], []
|
||||
self.module_name, self.verbose_name = None, None
|
||||
self.verbose_name_plural = None
|
||||
self.db_table = ''
|
||||
self.ordering = []
|
||||
self.unique_together = []
|
||||
self.where_constraints = []
|
||||
self.exceptions = []
|
||||
self.permissions = []
|
||||
self.object_name, self.app_label = None, None
|
||||
self.get_latest_by = None
|
||||
self.order_with_respect_to = None
|
||||
self.module_constants = {}
|
||||
self.admin = None
|
||||
self.meta = meta
|
||||
def merge_meta(self):
|
||||
meta_attrs = self.meta.__dict__
|
||||
del meta_attrs['__module__']
|
||||
del meta_attrs['__doc__']
|
||||
for attr_name in default_names:
|
||||
setattr(self, attr_name, meta_attrs.pop(attr_name, getattr(self, attr_name)))
|
||||
if meta_attrs != {}:
|
||||
raise TypeError, "'class META' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
self.model = cls
|
||||
cls._meta = self
|
||||
self.object_name = cls.__name__
|
||||
self.module_name = get_module_name(self.object_name )
|
||||
# If the verbose_name wasn't given, use the class name,
|
||||
# converted from "InitialCaps" to "lowercase with spaces".
|
||||
self.verbose_name = get_verbose_name(self.object_name)
|
||||
self.verbose_name_plural = self.verbose_name + 's'
|
||||
if self.meta:
|
||||
self.merge_meta()
|
||||
del self.meta
|
||||
|
||||
def _prepare(self):
|
||||
if self.order_with_respect_to:
|
||||
@ -77,6 +102,7 @@ class Options:
|
||||
def add_field(self, field):
|
||||
# Insert the given field in the order in which it was created, using
|
||||
# the "creation_counter" attribute of the field.
|
||||
# Move many-to-many related fields from self.fields into self.many_to_many.
|
||||
if field.rel and isinstance(field.rel, ManyToMany):
|
||||
self.many_to_many.insert(bisect(self.many_to_many, field), field)
|
||||
else:
|
||||
|
Loading…
x
Reference in New Issue
Block a user