magic-removal: Moved method_get_related and method_add_related to methods on Model, and changed Model._prepare() to add them. This doesn't currently work because _prepare() is called during the metaclass and related models don't yet exist at that point
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1617 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
76852e5da1
commit
d68487e8da
|
@ -928,6 +928,34 @@ class Model:
|
|||
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)
|
||||
|
||||
# Add "get_thingie", "get_thingie_count" and "get_thingie_list" methods
|
||||
# for all related objects.
|
||||
for related in cls._meta.get_all_related_objects():
|
||||
# Determine whether this related object is in another app.
|
||||
# If it's in another app, the method names will have the app
|
||||
# label prepended, and the add_BLAH() method will not be
|
||||
# generated.
|
||||
rel_obj_name = related.get_method_name_part()
|
||||
if isinstance(related.field.rel, meta.OneToOne):
|
||||
# Add "get_thingie" methods for one-to-one related objects.
|
||||
# EXAMPLE: Place.get_restaurants_restaurant()
|
||||
setattr(cls, 'get_%s' % rel_obj_name, curry(cls.__get_related, method_name='get_object', rel_class=related.model, rel_field=related.field))
|
||||
elif isinstance(related.field.rel, meta.ManyToOne):
|
||||
# Add "get_thingie" methods for many-to-one related objects.
|
||||
# EXAMPLE: Poll.get_choice()
|
||||
setattr(cls, 'get_%s' % rel_obj_name, curry(cls.__get_related, method_name='get_object', rel_class=related.model, rel_field=related.field))
|
||||
# Add "get_thingie_count" methods for many-to-one related objects.
|
||||
# EXAMPLE: Poll.get_choice_count()
|
||||
setattr(cls, 'get_%s_count' % rel_obj_name, curry(cls.__get_related, method_name='get_count', rel_class=related.model, rel_field=related.field))
|
||||
# Add "get_thingie_list" methods for many-to-one related objects.
|
||||
# EXAMPLE: Poll.get_choice_list()
|
||||
setattr(cls, 'get_%s_list' % rel_obj_name, curry(cls.__get_related, method_name='get_list', rel_class=related.model, rel_field=related.field))
|
||||
# Add "add_thingie" methods for many-to-one related objects,
|
||||
# but only for related objects that are in the same app.
|
||||
# EXAMPLE: Poll.add_choice()
|
||||
if related.opts.app_label == cls._meta.app_label:
|
||||
setattr(cls, 'add_%s' % rel_obj_name, curry(cls.__add_related, rel_class=related.model, rel_field=related.field))
|
||||
|
||||
_prepare = classmethod(_prepare)
|
||||
|
||||
def save(self):
|
||||
|
@ -1195,6 +1223,24 @@ class Model:
|
|||
|
||||
__set_many_to_many_objects.alters_data = True
|
||||
|
||||
def __get_related(self, method_name, rel_class, rel_field, **kwargs):
|
||||
kwargs['%s__%s__exact' % (rel_field.name, rel_field.rel.to._meta.pk.name)] = getattr(self, rel_field.rel.get_related_field().attname)
|
||||
kwargs.update(rel_field.rel.lookup_overrides)
|
||||
return getattr(rel_class.objects, method_name)(**kwargs)
|
||||
|
||||
def __add_related(self, rel_class, rel_field, *args, **kwargs):
|
||||
init_kwargs = dict(zip([f.attname for f in rel_class._meta.fields if f != rel_field and not isinstance(f, AutoField)], args))
|
||||
init_kwargs.update(kwargs)
|
||||
for f in rel_class._meta.fields:
|
||||
if isinstance(f, AutoField):
|
||||
init_kwargs[f.attname] = None
|
||||
init_kwargs[rel_field.name] = self
|
||||
obj = rel_class(**init_kwargs)
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
__add_related.alters_data = True
|
||||
|
||||
class Manager(object):
|
||||
def __init__(self, model_class):
|
||||
self.klass = model_class
|
||||
|
@ -1390,29 +1436,6 @@ class Manager(object):
|
|||
|
||||
# RELATIONSHIP METHODS #####################
|
||||
|
||||
# Handles related-object retrieval.
|
||||
# Examples: Poll.get_choice(), Poll.get_choice_list(), Poll.get_choice_count()
|
||||
def method_get_related(method_name, rel_mod, rel_field, self, **kwargs):
|
||||
if self._meta.has_related_links and rel_mod.Klass._meta.module_name == 'relatedlinks':
|
||||
kwargs['object_id__exact'] = getattr(self, rel_field.rel.field_name)
|
||||
else:
|
||||
kwargs['%s__%s__exact' % (rel_field.name, rel_field.rel.to._meta.pk.name)] = getattr(self, rel_field.rel.get_related_field().attname)
|
||||
kwargs.update(rel_field.rel.lookup_overrides)
|
||||
return getattr(rel_mod.Klass.objects, method_name)(**kwargs)
|
||||
|
||||
# Handles adding related objects.
|
||||
# Example: Poll.add_choice()
|
||||
def method_add_related(rel_obj, rel_mod, rel_field, self, *args, **kwargs):
|
||||
init_kwargs = dict(zip([f.attname for f in rel_obj.fields if f != rel_field and not isinstance(f, AutoField)], args))
|
||||
init_kwargs.update(kwargs)
|
||||
for f in rel_obj.fields:
|
||||
if isinstance(f, AutoField):
|
||||
init_kwargs[f.attname] = None
|
||||
init_kwargs[rel_field.name] = self
|
||||
obj = rel_mod.Klass(**init_kwargs)
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
# Handles related many-to-many object retrieval.
|
||||
# Examples: Album.get_song(), Album.get_song_list(), Album.get_song_count()
|
||||
def method_get_related_many_to_many(method_name, opts, rel_mod, rel_field, self, **kwargs):
|
||||
|
|
Loading…
Reference in New Issue