If I have a django model that has an field called 'order' (integer field that tracks the modifiable order of a specific model instance amongst all model instances), and I also want to track the position of the model instance based on that order ('first'/'mid'/'last'), is it better to have another model field called 'position', which I recalculate and store each time there is a change to order, or should I have a model method called 'get_position' which I call each time I need a position. I'm trying to work out which is more efficient. Whilst I won't need the position information each time I create/delete/modify a instance order, I will need that position field quite a bit within my templates.
CodePudding user response:
Generally avoid creating an additional database fields if something can be calculated from data already in the db, to prevent redundancy and reduce vectors for errors.
A method may work if its relatively simple, deriving its value from an existing field within the record. If it needs to look up comparative values from other records that would be an efficiency issue.
As you mention use in templates specifically, it may be worth seeing if the template builtins can meet your requirements.
Say your recordset is already in order of the 'order' field eg, MyRecords.objects.order_by('order')
When looping through MyRecords_context in a template using a for loop, you can test for {{if forloop.first}} or {{if forloop.last }} - you can also refer to MyRecords_context.first() and .last() to single those out. If you need the specific index of a given record in that particular recordset for you template, you can refer to {{ forloop.counter }} eg {{if forloop.counter < 10 and forloop.counter > 5}} or {{if forloop.counter == 5}}
The advantage of this approach is that if you have a filtered a subset of your records, you are still referring to the first, last or Nth records of the recordset, even though they may not be first and last overall in your absolute position field, and with no additional db calls.