Opened 7 weeks ago

Last modified 7 weeks ago

#35641 closed New feature

Pattern matching on model objects — at Version 2

Reported by: Johan Dahlin Owned by:
Component: Database layer (models, ORM) Version: 5.0
Severity: Normal Keywords:
Cc: Johan Dahlin Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Johan Dahlin)

It would be nice if I could use pattern matching on Django model fields, this is especially important in context where I don't know what the model is, for example in a global post_save() handler where I want to do some specific logic based on a subclass.

class Person(Model):
    name = TextField(...)
    age = IntegerField(...)

class Company(Model):
    address = TextField(...)

I would then be able to do

@receiver(pre_save)
def pre_save(sender, instance, ....):
   # model comes in via signals or some other way, we don't know which subclass it is
   match model:
      # equivalent to isinstance(model, Person) and model.age > 10:
       case Person(age) if age> 10:
            ....
      # equivalent to isinstance(model, Company) and model.name.endswith('Street')
       case Company(address) if name.endswith('Street'):
            ....
       # or just extract and return a value
       case Person(name):
           return name

Since match_args must be a tuple, the attribute must be generated inside a metaclass.

{{{#!python

@property
def match_args(self) -> tuple[str, ...]:

return tuple(f.name for f in self._meta.get_fields())

}}}

Happy to create a PR if this is interesting.

Change History (2)

comment:1 by Johan Dahlin, 7 weeks ago

I removed an earlier comment about a simple/straight-forward implementation using a @property but it won't work as, match_args needs to be a tuple and cannot be a property, so my suggested implementation above is too simplistic. I real one would have to be a bit more involved and generate the values and create a tuple inside the models metaclass.

Last edited 7 weeks ago by Johan Dahlin (previous) (diff)

comment:2 by Johan Dahlin, 7 weeks ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top