#31683 closed Bug (invalid)
Overridden methods ignored in models.DecimalField subclass
Reported by: | Max Rothman | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 2.2 |
Severity: | Normal | Keywords: | custom-model-fields |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Django: 2.2.4
Python: 3.6.9
Mysql: 5.6.47
It appears to be impossible to override any methods in subclasses of models.DecimalField
under certain circumstances. Consider the following:
class Field1(models.DecimalField): def get_prep_value(self, value): 1/0 class Field2(models.PositiveIntegerField): def get_prep_value(self, value): 1/0 class TestModel1(models.Model): m = Field1(max_digits=5, decimal_places=2) class TestModel2(models.Model): m = Field2() TestModel1(m=1).save() # No error! TestModel2(m=1).save() # Error, as expected
I'd expect to get an error when saving TestModel1
because get_prep_value should throw a ZeroDivisionError
, but as far as I can tell, Field1.get_prep_value
is never called.
This bug appears to be somewhat sensitive to platform conditions. I've been able to replicate it consistently on my machine, but another one of my colleagues who tried was not.
Change History (5)
comment:1 by , 5 years ago
Resolution: | → invalid |
---|---|
Severity: | Release blocker → Normal |
Status: | new → closed |
follow-up: 3 comment:2 by , 5 years ago
The docs do not mention anywhere that get_prep_value
is expected to be called in get_db_prep_value
on save, nor that DecimalField
behaves differently from most other fields in this respect. Could this be reopened as a documentation bug?
comment:3 by , 5 years ago
The docs do not mention anywhere that
get_prep_value
is expected to be called inget_db_prep_value
on save,...
It's not required, I just wanted to explain why exception is raised in .save()
for PositiveIntegerField
.
...nor that
DecimalField
behaves differently from most other fields in this respect. Could this be reopened as a documentation bug?
I don't think so, we cannot document implementation details of all builtin fields.
follow-up: 5 comment:4 by , 5 years ago
So as a django user the way I was supposed to find this out was to read the source code? The fact that this issue exists is proof that there is at least some kind of documentation issue.
comment:5 by , 5 years ago
Replying to Max Rothman:
So as a django user the way I was supposed to find this out was to read the source code?
Writing a custom model field is quite advanced usage. You can create a subclass of Field
and implement methods described in the How-to. If you want to create a subclass of the builtin fields you can also implement all methods or check an implementation and use relations between them. I don't see any contradiction.
The fact that this issue exists is proof that there is at least some kind of documentation issue.
I don't see any issue here. If you want to raise an exception when converting values to database values you should override get_db_prep_value()
as documented.
Overriding works fine.
DecimalField
doesn't callget_prep_value()
on.save()
because it has a customget_db_prep_save()
implementation: