1

Is there a way to make a Peewee model's field be based on a method of an instance of that model? In particular, I would like the default of field b to be based on field a plus some logic. Field default parameters allow for a callable, but I've been unable to find a way to reference the other fields during this callable.

I would hope for something like the below code, expect, of course, an instance method can't be called during the class static attribute definitions:

class CustomModel(Model):
    a = IntegerField()
    b = IntegerField(default=self.generate_b_from_a)  # Of course, `self` cannot be used here.

    def generate_b_from_a(self):
        value_to_be_used_for_b = sufficiently_complex_logic(self.a)
        return value_to_be_used_for_b

I have also considered overriding the save method to perform this action as seen in this answer, however, as the comments of that answer note, overriding save will not cover other methods of data creation (e.g., data created using the update method). The logic is sufficiently complex that it's impractical to move it to SQL logic.

Is there some way to use one field to determine the default of another field and have it apply to any operation where the default might be created?

golmschenk
  • 11,736
  • 20
  • 78
  • 137

1 Answers1

1

I think it's important to differentiate logic that belongs in the SQL/db layer vs the application layer. IMO, there's nothing wrong with adding complex "pre-save" logic to the application layer. You just need to properly enforce that your application always uses those methods to CRUD those objects.

I have a huge application that overrides peewee's save() method to call a _pre_save() method/hook that handles validation, complex default value calculation, etc. and it works great. This means that I rarely/carefully use peewee's update() and delete() queries because they will bypass this logic.

IMO, shoe-horning complex logic into the SQL-layer is just begging for problems. Just follow proper abstraction/APIs and you should be fine.

booshong
  • 782
  • 6
  • 21