Next order value for Django model instance

Assume, we have Django model with special weight integer field for ordering. We may want to assign its value automatically on save. Here’s the snippet implementing such behaviour:

class MyModel(models.Model):
    # some fields...
    weight = models.IntegerField(default=0)

    class Meta:
        ardering = ('weight',)

    def save(self, *args, **kwargs):
        self.weight = get_next_value(self, field_name='weight')
        super(MyModel, self).save(*args, **kwargs)

Here’s the get_next_value implementation:

def get_next_value(instance, field_name='order', step=10, **filter):
    model = instance.__class__
    qs = model.objects.order_by('-%s' % field_name)
    if filter:
        qs = qs.filter(**filter)
    try:
        max_value = getattr(qs[:1][0], field_name, 0)
    except IndexError:
        max_value = 0
    return (max_value / step + 1) * step

The implementation above can handle any field name with specified step. It can also provide next field value for filtered queryset.

Provided snippet is a part of halfbit-web-helpers collection.

  1. kodoblog posted this