#20205: PositiveIntegerfield does not handle empty values well -------------------------------------+------------------------------------- Reporter: anonymous | Owner: AmiZya Type: Bug | Status: assigned Component: Database layer | Version: master (models, ORM) | Resolution: Severity: Normal | Triage Stage: Accepted Keywords: | Needs documentation: 0 Has patch: 1 | Patch needs improvement: 1 Needs tests: 0 | UI/UX: 0 Easy pickings: 0 | -------------------------------------+-------------------------------------
Comment (by Adam Easterling <easterling.adam@…>): After thinking about this issue at some length myself, I agree with loic84: The real problem is that Model doesn't call a field's clean method in the case that the value is "empty." That logic doesn't seem to belong to the Model. To me, it seems that this logic should be moved to the field class, so each field could decide what's a valid "empty value" and what isn't. Furthermore, there's a comment near the aformentioned Model logic that says, "Skip validation for empty fields with blank=True. The developer is responsible for making sure they have a valid value." This is odd to me -- the developer is responsible for making sure that fields have a valid value, but where would that appropriately be done? You can't add a validator to the field, as clean() isn't run for that field. Any remaining solutions seem rather hacky. My own solution was to just override all number fields and change how they work, but I'm not super proud of it. Here's an example for Integers: {{{ class FixedIntegerMixin(object): ''' If you attempt to save an int field with a blank string, Django doesn't convert that to a None object, which is what the db expects. Also, if the value is "blank" according to Django (see EMPTY_VALUES found at django.core.validators) it won't call to_python for that field (see full_clean at django.db.models.base). This means that we have to override get_prep_value itself. ''' def get_prep_value(self, value): if value is None: return None if value == "": return None return int(value) class IntegerField(FixedIntegerMixin, IntegerField_django): pass class SmallIntegerField(FixedIntegerMixin, SmallIntegerField_django): pass class PositiveIntegerField(FixedIntegerMixin, PositiveIntegerField_django): pass class PositiveSmallIntegerField(FixedIntegerMixin, PositiveSmallIntegerField_django): pass }}} -- Ticket URL: <https://code.djangoproject.com/ticket/20205#comment:19> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/067.52b49cfaa74efee6021db742db2a1507%40djangoproject.com. For more options, visit https://groups.google.com/groups/opt_out.