Ticket #746: meta_models.patch

File meta_models.patch, 9.3 KB (added by ian@…, 18 years ago)

Meta Model Patch

  • 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            del related # clean up
    6325
    6426        # Do the same for all related many-to-many objects.
    6527        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
     28            related.field.rel.setup_relationships( related, meta, klass)
     29            del related # clean up
    7730
    7831        # Add "set_thingie_order" and "get_thingie_order" methods for objects
    7932        # that are ordered with respect to this.
  • core/meta/fields.py

     
    806806        "Returns the Field in the 'to' object to which this relationship is tied."
    807807        return self.to.get_field(self.field_name)
    808808
     809    def setup_relationships(self, related, meta, klass):
     810        " Add the 'get_thingie', 'get_thingie_count' and 'get_thingie_list' methods "
     811        rel_mod = related.opts.get_model_module()
     812        rel_obj_name = related.get_method_name_part()
     813        # Add "get_thingie" methods for many-to-one related objects.
     814        # EXAMPLE: Poll.get_choice()
     815        func = curry(meta.method_get_related, 'get_object', rel_mod, related.field)
     816        func.__doc__ = "Returns the associated `%s.%s` object matching the given criteria." % \
     817            (related.opts.app_label, related.opts.module_name)
     818        setattr(klass, 'get_%s' % rel_obj_name, func)
     819        # Add "get_thingie_count" methods for many-to-one related objects.
     820        # EXAMPLE: Poll.get_choice_count()
     821        func = curry(meta.method_get_related, 'get_count', rel_mod, related.field)
     822        func.__doc__ = "Returns the number of associated `%s.%s` objects." % \
     823            (related.opts.app_label, related.opts.module_name)
     824        setattr(klass, 'get_%s_count' % rel_obj_name, func)
     825        # Add "get_thingie_list" methods for many-to-one related objects.
     826        # EXAMPLE: Poll.get_choice_list()
     827        func = curry(meta.method_get_related, 'get_list', rel_mod, related.field)
     828        func.__doc__ = "Returns a list of associated `%s.%s` objects." % \
     829             (related.opts.app_label, related.opts.module_name)
     830        setattr(klass, 'get_%s_list' % rel_obj_name, func)
     831        # Add "add_thingie" methods for many-to-one related objects,
     832        # but only for related objects that are in the same app.
     833        # EXAMPLE: Poll.add_choice()
     834        if related.opts.app_label == klass._meta.app_label:
     835            func = curry(meta.method_add_related, related.opts, rel_mod, related.field)
     836            func.alters_data = True
     837            setattr(klass, 'add_%s' % rel_obj_name, func)
     838        del func, rel_obj_name, rel_mod # clean up
     839
     840
    809841class ManyToMany:
    810842    def __init__(self, to, singular=None, num_in_admin=0, related_name=None,
    811843        filter_interface=None, limit_choices_to=None, raw_id_admin=False):
     
    819851        self.raw_id_admin = raw_id_admin
    820852        assert not (self.raw_id_admin and self.filter_interface), "ManyToMany relationships may not use both raw_id_admin and filter_interface"
    821853
     854    def setup_relationships(self, related, meta, klass):
     855        " Add 'get_thingie', 'get_thingie_count' and 'get_thingie_list' methods"
     856        rel_mod = related.opts.get_model_module()
     857        rel_obj_name = related.get_method_name_part()
     858        setattr(klass, 'get_%s' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_object', klass._meta, rel_mod, related.field))
     859        setattr(klass, 'get_%s_count' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_count', klass._meta, rel_mod, related.field))
     860        setattr(klass, 'get_%s_list' % rel_obj_name, curry(meta.method_get_related_many_to_many, 'get_list', klass._meta, rel_mod, related.field))
     861        if related.opts.app_label == klass._meta.app_label:
     862            func = curry(meta.method_set_related_many_to_many, related.opts, related.field)
     863            func.alters_data = True
     864            setattr(klass, 'set_%s' % related.opts.module_name, func)
     865            del func
     866
     867        del rel_obj_name, rel_mod # clean up
     868
     869
    822870class OneToOne(ManyToOne):
    823871    def __init__(self, to, field_name, num_in_admin=0, edit_inline=False,
    824872        related_name=None, limit_choices_to=None, lookup_overrides=None,
     
    830878        self.lookup_overrides = lookup_overrides or {}
    831879        self.raw_id_admin = raw_id_admin
    832880
     881    def setup_relationships(self, related, meta, klass):
     882        " Add the 'get_thingie' "
     883        rel_mod = related.opts.get_model_module()
     884        rel_obj_name = related.get_method_name_part()
     885        # Add "get_thingie" methods for one-to-one related objects.
     886        # EXAMPLE: Place.get_restaurants_restaurant()
     887        func = curry(meta.method_get_related, 'get_object', rel_mod, related.field)
     888        func.__doc__ = "Returns the associated `%s.%s` object." % (related.opts.app_label, related.opts.module_name)
     889        setattr(klass, 'get_%s' % rel_obj_name, func)
     890
     891        del func, rel_obj_name, rel_mod # clean up
     892
     893
    833894class BoundFieldLine(object):
    834895    def __init__(self, field_line, field_mapping, original, bound_field_class=BoundField):
    835896        self.bound_fields = [field.bind(field_mapping, original, bound_field_class)
Back to Top