[Django] #35641: Pattern matching on model objects

27 views
Skip to first unread message

Django

unread,
Jul 30, 2024, 4:39:23 AM7/30/24
to django-...@googlegroups.com
#35641: Pattern matching on model objects
-------------------------------------+-------------------------------------
Reporter: jdahlin | Type: New
| feature
Status: new | Component: Database
| layer (models, ORM)
Version: 5.0 | Severity: Normal
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
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.


{{{#!python
class Person(Model):
name = TextField(...)
age = IntegerField(...)

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

I would then be able to do
{{{#!python
@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
}}}

The implementation for this is fairly straight-forward, add this to
models.Model.

{{{#!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.
--
Ticket URL: <https://code.djangoproject.com/ticket/35641>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Jul 30, 2024, 4:48:31 AM7/30/24
to django-...@googlegroups.com
#35641: Pattern matching on model objects
-------------------------------------+-------------------------------------
Reporter: jdahlin | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by jdahlin):

Sorry, I got confused, __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.
--
Ticket URL: <https://code.djangoproject.com/ticket/35641#comment:1>

Django

unread,
Jul 30, 2024, 4:49:28 AM7/30/24
to django-...@googlegroups.com
#35641: Pattern matching on model objects
-------------------------------------+-------------------------------------
Reporter: jdahlin | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by jdahlin:

Old description:
New description:
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.

--
--
Ticket URL: <https://code.djangoproject.com/ticket/35641#comment:2>

Django

unread,
Jul 30, 2024, 4:49:55 AM7/30/24
to django-...@googlegroups.com

Django

unread,
Jul 30, 2024, 9:08:23 AM7/30/24
to django-...@googlegroups.com
#35641: Pattern matching on model objects
-------------------------------------+-------------------------------------
Reporter: Johan Dahlin | Owner: (none)
Type: New feature | Status: new
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):

I think we'd have to see a PR and how invasive it is to implement before
taking a decision here. I personally only see marginal readability gains
in the example you provided so I'm skeptical that's worth the complexity.
--
Ticket URL: <https://code.djangoproject.com/ticket/35641#comment:4>

Django

unread,
Jul 30, 2024, 10:33:56 AM7/30/24
to django-...@googlegroups.com
#35641: Pattern matching on model objects
-------------------------------------+-------------------------------------
Reporter: Johan Dahlin | Owner: (none)
Type: New feature | Status: closed
Component: Database layer | Version: 5.0
(models, ORM) |
Severity: Normal | Resolution: wontfix
Keywords: | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Natalia Bidart):

* resolution: => wontfix
* status: new => closed

Comment:

Hello Johan, welcome to the Django Community! Nice to see you again.

I personally like your proposal, but since Django is a community driven
project, there is a established procedure to request new features which
requires first gathering community consensus so then a ticket can be
accepted. To do that, please consider starting a new conversation on the
[https://forum.djangoproject.com/c/internals/5 Django Forum], where you'll
reach a wider audience and likely get extra feedback.

I'll close the ticket for now, but if there is a community agreement for
the feature request, you are welcome to come back to the ticket and point
to the forum topic, so we can then re-open it. For more details, please
see [https://docs.djangoproject.com/en/stable/internals/contributing/bugs-
and-features/#requesting-features the documented guidelines for requesting
features].

Thanks!
--
Ticket URL: <https://code.djangoproject.com/ticket/35641#comment:5>
Reply all
Reply to author
Forward
0 new messages