Ticket #2740: 2740.diff

File 2740.diff, 6.0 KB (added by Gulopine, 7 years ago)

Moved the order_with_respect_to curried methods so that they're added after model resolution

  • django/db/models/base.py

     
    191191        opts = cls._meta
    192192        opts._prepare(cls)
    193193
    194         if opts.order_with_respect_to:
    195             cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
    196             cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
    197             setattr(opts.order_with_respect_to.rel.to, 'get_%s_order' % cls.__name__.lower(), curry(method_get_order, cls))
    198             setattr(opts.order_with_respect_to.rel.to, 'set_%s_order' % cls.__name__.lower(), curry(method_set_order, cls))
    199 
    200194        # Give the class a docstring -- its definition.
    201195        if cls.__doc__ is None:
    202196            cls.__doc__ = "%s(%s)" % (cls.__name__, ", ".join([f.attname for f in opts.fields]))
     
    436430            setattr(self, cachename, get_image_dimensions(filename))
    437431        return getattr(self, cachename)
    438432
    439 ############################################
    440 # HELPER FUNCTIONS (CURRIED MODEL METHODS) #
    441 ############################################
    442 
    443 # ORDERING METHODS #########################
    444 
    445 def method_set_order(ordered_obj, self, id_list):
    446     qn = connection.ops.quote_name
    447     cursor = connection.cursor()
    448     # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
    449     sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
    450         (qn(ordered_obj._meta.db_table), qn('_order'),
    451         qn(ordered_obj._meta.order_with_respect_to.column),
    452         qn(ordered_obj._meta.pk.column))
    453     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
    454     cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
    455     transaction.commit_unless_managed()
    456 
    457 def method_get_order(ordered_obj, self):
    458     qn = connection.ops.quote_name
    459     cursor = connection.cursor()
    460     # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
    461     sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \
    462         (qn(ordered_obj._meta.pk.column),
    463         qn(ordered_obj._meta.db_table),
    464         qn(ordered_obj._meta.order_with_respect_to.column),
    465         qn('_order'))
    466     rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
    467     cursor.execute(sql, [rel_val])
    468     return [r[0] for r in cursor.fetchall()]
    469 
    470433##############################################
    471434# HELPER FUNCTIONS (CURRIED MODEL FUNCTIONS) #
    472435##############################################
  • django/db/models/fields/related.py

     
    8282        related = RelatedObject(other, cls, self)
    8383        self.contribute_to_related_class(other, related)
    8484
     85        opts = other._meta
     86
     87        if opts.order_with_respect_to:
     88            other.get_next_in_order = curry(other._get_next_or_previous_in_order, is_next=True)
     89            other.get_previous_in_order = curry(other._get_next_or_previous_in_order, is_next=False)
     90            setattr(opts.order_with_respect_to.rel.to, 'get_%s_order' % other.__name__.lower(), curry(method_get_order, other))
     91            setattr(opts.order_with_respect_to.rel.to, 'set_%s_order' % other.__name__.lower(), curry(method_set_order, other))
     92
    8593    def get_db_prep_lookup(self, lookup_type, value):
    8694        # If we are doing a lookup on a Related Field, we must be
    8795        # comparing object instances. The value should be the PK of value,
     
    823831        self.multiple = True
    824832
    825833        assert not (self.raw_id_admin and self.filter_interface), "ManyToManyRels may not use both raw_id_admin and filter_interface"
     834
     835############################################
     836# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
     837############################################
     838
     839# ORDERING METHODS #########################
     840
     841def method_set_order(ordered_obj, self, id_list):
     842    qn = connection.ops.quote_name
     843    cursor = connection.cursor()
     844    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
     845    sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
     846        (qn(ordered_obj._meta.db_table), qn('_order'),
     847        qn(ordered_obj._meta.order_with_respect_to.column),
     848        qn(ordered_obj._meta.pk.column))
     849    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
     850    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
     851    transaction.commit_unless_managed()
     852
     853def method_get_order(ordered_obj, self):
     854    qn = connection.ops.quote_name
     855    cursor = connection.cursor()
     856    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
     857    sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \
     858        (qn(ordered_obj._meta.pk.column),
     859        qn(ordered_obj._meta.db_table),
     860        qn(ordered_obj._meta.order_with_respect_to.column),
     861        qn('_order'))
     862    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
     863    cursor.execute(sql, [rel_val])
     864    return [r[0] for r in cursor.fetchall()]
  • tests/regressiontests/many_to_one_regress/models.py

     
    2323    name = models.CharField(max_length=20)
    2424    parent = models.ForeignKey(Parent)
    2525
     26# If ticket #2740 ever slips back in, this model will not be able to be
     27# created (order_with_respect_to on a self-referencing relationship).
    2628
     29class Category(models.Model):
     30   parent = models.ForeignKey('self')
     31
     32   class Meta:
     33       order_with_respect_to = 'parent'
     34
     35
    2736__test__ = {'API_TESTS':"""
    2837>>> Third.AddManipulator().save(dict(id='3', name='An example', another=None))
    2938<Third: Third object>
Back to Top