Ticket #746: meta_models_2.patch

File meta_models_2.patch, 9.7 KB (added by ian@…, 18 years ago)

now hangs of the fields instead

  • models/__init__.py

     
    2020        # Add "get_thingie", "get_thingie_count" and "get_thingie_list" methods
    2121        # for all related objects.
    2222        for related in klass._meta.get_all_related_objects():
    23             # Determine whether this related object is in another app.
    24             # If it's in another app, the method names will have the app
    25             # label prepended, and the add_BLAH() method will not be
    26             # generated.
    27             rel_mod = related.opts.get_model_module()
    28             rel_obj_name = related.get_method_name_part()
    29             if isinstance(related.field.rel, meta.OneToOne):
    30                 # Add "get_thingie" methods for one-to-one related objects.
    31                 # EXAMPLE: Place.get_restaurants_restaurant()
    32                 func = curry(meta.method_get_related, 'get_object', rel_mod, related.field)
    33                 func.__doc__ = "Returns the associated `%s.%s` object." % (related.opts.app_label, related.opts.module_name)
    34                 setattr(klass, 'get_%s' % rel_obj_name, func)
    35             elif isinstance(related.field.rel, meta.ManyToOne):
    36                 # Add "get_thingie" methods for many-to-one related objects.
    37                 # EXAMPLE: Poll.get_choice()
    38                 func = curry(meta.method_get_related, 'get_object', rel_mod, related.field)
    39                 func.__doc__ = "Returns the associated `%s.%s` object matching the given criteria." % \
    40                     (related.opts.app_label, related.opts.module_name)
    41                 setattr(klass, 'get_%s' % rel_obj_name, func)
    42                 # Add "get_thingie_count" methods for many-to-one related objects.
    43                 # EXAMPLE: Poll.get_choice_count()
    44                 func = curry(meta.method_get_related, 'get_count', rel_mod, related.field)
    45                 func.__doc__ = "Returns the number of associated `%s.%s` objects." % \
    46                     (related.opts.app_label, related.opts.module_name)
    47                 setattr(klass, 'get_%s_count' % rel_obj_name, func)
    48                 # Add "get_thingie_list" methods for many-to-one related objects.
    49                 # EXAMPLE: Poll.get_choice_list()
    50                 func = curry(meta.method_get_related, 'get_list', rel_mod, related.field)
    51                 func.__doc__ = "Returns a list of associated `%s.%s` objects." % \
    52                      (related.opts.app_label, related.opts.module_name)
    53                 setattr(klass, 'get_%s_list' % rel_obj_name, func)
    54                 # Add "add_thingie" methods for many-to-one related objects,
    55                 # but only for related objects that are in the same app.
    56                 # EXAMPLE: Poll.add_choice()
    57                 if related.opts.app_label == klass._meta.app_label:
    58                     func = curry(meta.method_add_related, related.opts, rel_mod, related.field)
    59                     func.alters_data = True
    60                     setattr(klass, 'add_%s' % rel_obj_name, func)
    61                 del func
    62             del rel_obj_name, rel_mod, related # clean up
     23#            related.field.rel.setup_relationships( related, meta, klass)
     24            related.field.setup_relationships( related, meta, klass)
     25            del related # clean up
    6326
    6427        # Do the same for all related many-to-many objects.
    6528        for related in klass._meta.get_all_related_many_to_many_objects():
    66             rel_mod = related.opts.get_model_module()
    67             rel_obj_name = related.get_method_name_part()
    68             setattr(klass, 'get_%s' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_object', klass._meta, rel_mod, related.field))
    69             setattr(klass, 'get_%s_count' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_count', klass._meta, rel_mod, related.field))
    70             setattr(klass, 'get_%s_list' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_list', klass._meta, rel_mod, related.field))
    71             if related.opts.app_label == klass._meta.app_label:
    72                 func = curry(meta.method_set_related_many_to_many, related.opts, related.field)
    73                 func.alters_data = True
    74                 setattr(klass, 'set_%s' % related.opts.module_name, func)
    75                 del func
    76             del rel_obj_name, rel_mod, related # clean up
     29            related.field.setup_relationships( related, meta, klass)
     30            del related # clean up
    7731
    7832        # Add "set_thingie_order" and "get_thingie_order" methods for objects
    7933        # that are ordered with respect to this.
  • core/meta/fields.py

     
    704704                  return { self.name : choice_list[1][0] }
    705705        return Field.flatten_data(self, follow, obj)
    706706
     707    def setup_relationships(self, related, meta, klass):
     708        " Add the 'get_thingie', 'get_thingie_count' and 'get_thingie_list' methods "
     709        rel_mod = related.opts.get_model_module()
     710        rel_obj_name = related.get_method_name_part()
     711        # Add "get_thingie" methods for many-to-one related objects.
     712        # EXAMPLE: Poll.get_choice()
     713        func = curry(meta.method_get_related, 'get_object', rel_mod, self )
     714        func.__doc__ = "Returns the associated `%s.%s` object matching the given criteria." % \
     715            (related.opts.app_label, related.opts.module_name)
     716        setattr(klass, 'get_%s' % rel_obj_name, func)
     717        # Add "get_thingie_count" methods for many-to-one related objects.
     718        # EXAMPLE: Poll.get_choice_count()
     719        func = curry(meta.method_get_related, 'get_count', rel_mod, self )
     720        func.__doc__ = "Returns the number of associated `%s.%s` objects." % \
     721            (related.opts.app_label, related.opts.module_name)
     722        setattr(klass, 'get_%s_count' % rel_obj_name, func)
     723        # Add "get_thingie_list" methods for many-to-one related objects.
     724        # EXAMPLE: Poll.get_choice_list()
     725        func = curry(meta.method_get_related, 'get_list', rel_mod, self )
     726        func.__doc__ = "Returns a list of associated `%s.%s` objects." % \
     727             (related.opts.app_label, related.opts.module_name)
     728        setattr(klass, 'get_%s_list' % rel_obj_name, func)
     729        # Add "add_thingie" methods for many-to-one related objects,
     730        # but only for related objects that are in the same app.
     731        # EXAMPLE: Poll.add_choice()
     732        if related.opts.app_label == klass._meta.app_label:
     733            func = curry(meta.method_add_related, related.opts, rel_mod, self )
     734            func.alters_data = True
     735            setattr(klass, 'add_%s' % rel_obj_name, func)
     736        del func, rel_obj_name, rel_mod # clean up
     737
     738
    707739class ManyToManyField(Field):
    708740    def __init__(self, to, **kwargs):
    709741        kwargs['verbose_name'] = kwargs.get('verbose_name', to._meta.verbose_name_plural)
     
    765797                   new_data[self.name] = [choices_list[0][0]]
    766798        return new_data
    767799
     800    def setup_relationships(self, related, meta, klass):
     801        " Add 'get_thingie', 'get_thingie_count' and 'get_thingie_list' methods"
     802        rel_mod = related.opts.get_model_module()
     803        rel_obj_name = related.get_method_name_part()
     804        setattr(klass, 'get_%s' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_object', klass._meta, rel_mod, self))
     805        setattr(klass, 'get_%s_count' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_count', klass._meta, rel_mod, self))
     806        setattr(klass, 'get_%s_list' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_list', klass._meta, rel_mod, self))
     807        if related.opts.app_label == klass._meta.app_label:
     808            func = curry(meta.method_set_related_many_to_many, related.opts, self)
     809            func.alters_data = True
     810            setattr(klass, 'set_%s' % related.opts.module_name, func)
     811            del func
     812
     813        del rel_obj_name, rel_mod # clean up
     814
     815
    768816class OneToOneField(IntegerField):
    769817    def __init__(self, to, to_field=None, **kwargs):
    770818        kwargs['verbose_name'] = kwargs.get('verbose_name', 'ID')
     
    785833        kwargs['primary_key'] = True
    786834        IntegerField.__init__(self, **kwargs)
    787835
     836    def setup_relationships(self, related, meta, klass):
     837        " Add the 'get_thingie' "
     838        rel_mod = related.opts.get_model_module()
     839        rel_obj_name = related.get_method_name_part()
     840        # Add "get_thingie" methods for one-to-one related objects.
     841        # EXAMPLE: Place.get_restaurants_restaurant()
     842        func = curry(meta.method_get_related, 'get_object', rel_mod, self)
     843        func.__doc__ = "Returns the associated `%s.%s` object." % (related.opts.app_label, related.opts.module_name)
     844        setattr(klass, 'get_%s' % rel_obj_name, func)
     845
     846        del func, rel_obj_name, rel_mod # clean up
     847
     848
    788849class ManyToOne:
    789850    def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None,
    790851        max_num_in_admin=None, num_extra_on_change=1, edit_inline=False,
     
    806867        "Returns the Field in the 'to' object to which this relationship is tied."
    807868        return self.to.get_field(self.field_name)
    808869
     870
    809871class ManyToMany:
    810872    def __init__(self, to, singular=None, num_in_admin=0, related_name=None,
    811873        filter_interface=None, limit_choices_to=None, raw_id_admin=False):
     
    830892        self.lookup_overrides = lookup_overrides or {}
    831893        self.raw_id_admin = raw_id_admin
    832894
     895
    833896class BoundFieldLine(object):
    834897    def __init__(self, field_line, field_mapping, original, bound_field_class=BoundField):
    835898        self.bound_fields = [field.bind(field_mapping, original, bound_field_class)
Back to Top