magic-removal:Cleanups. Start of revised M2M.
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1720 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
06332287a8
commit
4f609faf3f
|
@ -27,7 +27,6 @@ get_module_name = lambda class_name: class_name.lower() + 's'
|
|||
get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip()
|
||||
|
||||
|
||||
|
||||
class ModelBase(type):
|
||||
"Metaclass for all models"
|
||||
def __new__(cls, name, bases, attrs):
|
||||
|
@ -42,7 +41,7 @@ class ModelBase(type):
|
|||
except KeyError:
|
||||
meta_attrs = {}
|
||||
|
||||
# Create the class, because we need it to use in currying.
|
||||
# Create the class, we need to add the options to it.
|
||||
new_class = type.__new__(cls, name, bases, { '__module__' : attrs.pop('__module__') })
|
||||
|
||||
opts = Options(
|
||||
|
@ -82,15 +81,10 @@ class ModelBase(type):
|
|||
opts.app_label = app_label
|
||||
|
||||
#Add all attributes to the class
|
||||
#fields, managers = [], []
|
||||
for obj_name, obj in attrs.items():
|
||||
new_class.add_to_class(obj_name, obj)
|
||||
|
||||
if not hasattr(new_class, '_default_manager'):
|
||||
# Create the default manager, if needed.
|
||||
if hasattr(new_class, 'objects'):
|
||||
raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % name
|
||||
new_class.add_to_class('objects', Manager())
|
||||
|
||||
|
||||
# Give the class a docstring -- its definition.
|
||||
if new_class.__doc__ is None:
|
||||
|
@ -102,9 +96,7 @@ class ModelBase(type):
|
|||
opts._prepare()
|
||||
new_class._prepare()
|
||||
|
||||
# If the db_table wasn't provided, use the app_label + module_name.
|
||||
if not opts.db_table:
|
||||
opts.db_table = "%s_%s" % (app_label, opts.module_name)
|
||||
|
||||
|
||||
# Populate the _MODELS member on the module the class is in.
|
||||
app_package.__dict__.setdefault('_MODELS', []).append(new_class)
|
||||
|
@ -175,6 +167,12 @@ class Model(object):
|
|||
dispatcher.send( signal = Signals.post_init, sender = self.__class__, instance=self)
|
||||
|
||||
def _prepare(cls):
|
||||
if not hasattr(cls, '_default_manager'):
|
||||
# Create the default manager, if needed.
|
||||
if hasattr(cls, 'objects'):
|
||||
raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % name
|
||||
cls.add_to_class('objects', Manager())
|
||||
|
||||
cls.add_to_class( 'AddManipulator', ModelAddManipulator)
|
||||
cls.add_to_class( 'ChangeManipulator', ModelChangeManipulator)
|
||||
|
||||
|
|
|
@ -37,9 +37,10 @@ class RelatedField(object):
|
|||
do_pending_lookups = classmethod(do_pending_lookups)
|
||||
|
||||
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
Field.contribute_to_class(self,cls,name)
|
||||
sup = super(RelatedField,self)
|
||||
if hasattr(sup, 'contribute_to_class'):
|
||||
sup.contribute_to_class(cls,name)
|
||||
other = self.rel.to
|
||||
if isinstance(other, basestring):
|
||||
if other == RECURSIVE_RELATIONSHIP_CONSTANT:
|
||||
|
@ -206,7 +207,7 @@ class OneToOneField(SharedMethods, IntegerField):
|
|||
|
||||
class ManyToManyField(RelatedField,Field):
|
||||
def __init__(self, to, **kwargs):
|
||||
kwargs['verbose_name'] = kwargs.get('verbose_name', to._meta.verbose_name_plural)
|
||||
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
|
||||
kwargs['rel'] = ManyToMany(to, kwargs.pop('singular', None),
|
||||
num_in_admin=kwargs.pop('num_in_admin', 0),
|
||||
related_name=kwargs.pop('related_name', None),
|
||||
|
@ -292,9 +293,53 @@ class ManyToManyField(RelatedField,Field):
|
|||
func.alters_data = True
|
||||
setattr(cls, 'set_%s' % related.opts.module_name, func)
|
||||
|
||||
self.rel.singular = self.rel.singular or self.rel.to._meta.object_name.lower()
|
||||
|
||||
def set_attributes_from_rel(self):
|
||||
pass
|
||||
|
||||
class ManyToManyFieldNew(RelatedField):
|
||||
def __init__(self, to, **kwargs):
|
||||
self.to = to
|
||||
self.from_ = None
|
||||
self.rel = self
|
||||
self.edit_inline = False
|
||||
|
||||
def set_attributes_from_rel(self):
|
||||
pass
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
self.from_ = cls
|
||||
self.name = name
|
||||
super(ManyToManyFieldNew, self).contribute_to_class(cls, name)
|
||||
|
||||
|
||||
def contribute_to_related_class(self, cls, name):
|
||||
#Now we know both classes exist.
|
||||
self.to = cls
|
||||
# We need to wait until the class we were in was fully defined
|
||||
dispatcher.connect(
|
||||
self.from_prepared,
|
||||
signal = Signals.class_prepared,
|
||||
sender = self.from_
|
||||
)
|
||||
|
||||
def from_prepared(self):
|
||||
from django.db.models.base import Model
|
||||
|
||||
class M2M(Model):
|
||||
__module__ = self.from_.__module__
|
||||
|
||||
id_to = self.from_._meta.db_table
|
||||
id_from = self.to._meta.db_table
|
||||
|
||||
M2M.add_to_class(id_from, ForeignKey(to=self.from_) )
|
||||
M2M.add_to_class(id_to, ForeignKey(to=self.to) )
|
||||
M2M._meta.db_table = '%s_%s' % (self.from_._meta.db_table, self.name)
|
||||
M2M._meta.unique_together = ((id_to, id_from),)
|
||||
M2M.__name__ = "M2M_%s_%s_%s" % (self.name,self.from_.__name__, self.to.__name__)
|
||||
|
||||
|
||||
class ManyToOne:
|
||||
def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None,
|
||||
max_num_in_admin=None, num_extra_on_change=1, edit_inline=False,
|
||||
|
@ -331,7 +376,7 @@ class ManyToMany:
|
|||
def __init__(self, to, singular=None, num_in_admin=0, related_name=None,
|
||||
filter_interface=None, limit_choices_to=None, raw_id_admin=False):
|
||||
self.to = to
|
||||
self.singular = singular or to._meta.object_name.lower()
|
||||
self.singular = singular or None
|
||||
self.num_in_admin = num_in_admin
|
||||
self.related_name = related_name
|
||||
self.filter_interface = filter_interface
|
||||
|
|
|
@ -13,9 +13,11 @@ class ManipulatorDescriptor(object):
|
|||
|
||||
def __get__(self, instance, type=None):
|
||||
if instance != None:
|
||||
raise "Manipulator accessed via instance"
|
||||
raise "Manipulator can not be accessed via instance"
|
||||
else:
|
||||
if not self.man:
|
||||
# Create a class which inherits from the MANIPULATOR class given in the class,
|
||||
# and the appropriate automatic manipulator,
|
||||
class Man(self.get_base_manipulator(type), self.base):
|
||||
pass
|
||||
|
||||
|
@ -25,6 +27,7 @@ class ManipulatorDescriptor(object):
|
|||
return self.man
|
||||
|
||||
def get_base_manipulator(self, type):
|
||||
|
||||
if hasattr(type, 'MANIPULATOR'):
|
||||
man = type.MANIPULATOR
|
||||
else:
|
||||
|
@ -60,17 +63,13 @@ class AutomaticManipulator(Manipulator):
|
|||
if self.follow.get(f.name, False):
|
||||
self.fields.extend(f.get_manipulator_fields(self.opts, self, self.change))
|
||||
|
||||
|
||||
# Add fields for related objects.
|
||||
for f in self.opts.get_all_related_objects():
|
||||
if self.follow.get(f.name, False):
|
||||
print f.name
|
||||
fol = self.follow[f.name]
|
||||
fields = f.get_manipulator_fields(self.opts, self, self.change, fol)
|
||||
print fields
|
||||
self.fields.extend(fields)
|
||||
|
||||
|
||||
def save(self, new_data):
|
||||
add, change, opts, klass = self.add, self.change, self.opts, self.model
|
||||
# TODO: big cleanup when core fields go -> use recursive manipulators.
|
||||
|
|
|
@ -71,6 +71,10 @@ class Options:
|
|||
self.has_auto_field = True
|
||||
#HACK
|
||||
self.limit_choices_to = {}
|
||||
|
||||
# If the db_table wasn't provided, use the app_label + module_name.
|
||||
if not self.db_table:
|
||||
self.db_table = "%s_%s" % (self.app_label, self.module_name)
|
||||
|
||||
def add_field(self, field):
|
||||
# Insert the fields in the order that they were created. The
|
||||
|
|
Loading…
Reference in New Issue