Wednesday, July 17, 2013

Django Models: Using Different Fields as a Single Field for Sorting


   Given a django model such that:

    a.) any instance could only have a single 'value'
    b.) this 'value' could be any model field (or type, say IntegerField, CharField, DateField)
    b.) and these 'values' will be used as basis for sorting.

How to:

I would assume someone who reads this know the basics of Django ORM. So..

    1.) First create a model and add the fields (where the 'value' will be saved), and don't forget to add 'null=True' and 'blank=True' appropriately (i.e. 'null=True' for IntegerField, 'null=True, blank=True' for CharField). An instance could have all these fields blank, or save a 'value' in only one of them since an instance COULD and SHOULD only have a single 'value';

    2.) Then, create methods that subscribe to the given conditions, such as a save method that can process input to select and save the 'value' in the appropriate field, and another method to fetch 'values' no matter which field they are stored. This would ensure that 'values' are stored and retrieved correctly.

    3.) Lastly, there's this question.. How do we create and order a query set with the restriction of using 'values', given that it is NOT a single database field?

For this, we can utilize the 'extra' method. For example, in MySQL we could do it as:

            q = MyModel.objects.extra(select={values': 'COALESCE(int_field, char_field, date_field)'})
            q = q.extra(order_by = ['values'])

So there we have it! We have a query set which we can process further using method chaining and slicing. We can even use it in django admin for sorting in the list display. Just customize/override the returned change list object (if  you are familiar with it) before it gets displayed.

More on the 'extra' query here

No comments:

Post a Comment