Opened 13 years ago
Closed 9 years ago
#18480 closed Bug (duplicate)
Inherited model fails to handle blank field properly
Reported by: | Yuval Adam | Owned by: | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.4 |
Severity: | Normal | Keywords: | |
Cc: | navi7 | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I just opened a stack overflow question about this, but after digging a bit this is starting to look like a bug.
Take two simple models with inheritance:
class A(models.Model): a = models.IntegerField(blank=True) class B(A): b = models.IntegerField(blank=True)
And then in runtime:
>>> A() <A: A object> >>> B() Traceback (most recent call last): File "<console>", line 1, in <module> File "django/db/models/base.py", line 357, in __init__ setattr(self, field.attname, val) File "django/db/models/fields/related.py", line 271, in __set__ (instance._meta.object_name, self.related.get_accessor_name())) ValueError: Cannot assign None: "B.b" does not allow null values.
There should be absolutely no reason why A() is properly created, while B() should fail.
Change History (8)
comment:1 by , 13 years ago
comment:2 by , 12 years ago
Triage Stage: | Unreviewed → Accepted |
---|
blank=True
is irrelevant here; blank
is validation-related and the example doesn't involve forms.
I reproduced the inconsistency and I agree that it's a bug.
I don't understand the comment above. yuval_a, are you sure you haven't misread the model definition?
comment:3 by , 12 years ago
Well, what's the bug here, in your opinion?
As far as I can tell I've made the error of having field names which are the same as model names in both examples.
It's odd that the error only reproduces on the sub-model. And the error should definitely be more descriptive.
comment:4 by , 11 years ago
Seems all related accessor name are not validated against existing fields.
class A(models.Model):
a = models.IntegerField()
br = models.IntegerField()
class B(models.Model):
a = models.ForeignKey(A, related_name='br')
raises an error.
Should fixing this wait till the validation changes hit?
comment:5 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:6 by , 10 years ago
This is a kind of red herring.
The actual problem stems from the model coming up with the same field name as name of the derived class itself so it can have the reference to the base class. Model building then just overwrites our field. The simplest test is this:
class FruitFly(models.Model): pass class CroatianFruitFly(FruitFly): croatianfruitfly = models.IntegerField() fly2 = CroatianFruitFly() # this throws wrong exception
The error thrown is:
ValueError: Cannot assign None: "CroatianFruitFly.croatianfruitfly" does not allow null values.
And that's totally misleading.
As I'm totally new to Django, I don't know a way out of it. It seems that using the same field name as the class can be explicitly forbidden by throwing meaningful errors when the model is built. Then again, that could potentially be a breaking change.
Or, the name of the reference could be mangled somehow to not use that exact name.
Anyways, I need someone who knows the internals a bit more to look at this.
comment:7 by , 10 years ago
Cc: | added |
---|---|
Owner: | removed |
Status: | assigned → new |
comment:8 by , 9 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
The clashing field/model names is a duplicate of #14217.
The issue here is a conflicting field name. This is totally irrelevant to the field being blank.
I would argue, though, that the error must be much more descriptive. And I still don't quite understand why this isn't an issue with the parent model.