Opened 14 years ago
Closed 13 years ago
#15953 closed New feature (wontfix)
Allow setting individual fields as 'unique' from the model Meta options
Reported by: | Julien Phalip | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | jonas-django@… | Triage Stage: | Design decision needed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I'm dealing with this case:
class A(models.Model): blah = models.CharField(max_length=100) class Meta: abstract = True class B(A): pass
... where A
is in a separate app than B
and is used in multiple different contexts. I need to have the blah
field be unique for B
, whereas it shouldn't necessarily be unique in every other context where it is used. The only way I've found so far is:
class B(A): pass B._meta.get_field('blah')._unique = True # Ugliness alert!
Is it envisageable to allow setting the unique
flag for individual fields from the Meta options, in the same way as with unique_together
? Something like this for example:
class B(A): class Meta: unique = ('blah',)
Change History (10)
comment:1 by , 14 years ago
Description: | modified (diff) |
---|
comment:2 by , 14 years ago
Description: | modified (diff) |
---|
follow-up: 4 comment:3 by , 14 years ago
Wouldn't overriding the blah
field in class B solve the issue?
comment:4 by , 14 years ago
Replying to jezdez:
Wouldn't overriding the
blah
field in class B solve the issue?
Unfortunately not -- you get the following error:
django.core.exceptions.FieldError: Local field 'blah' in class 'B' clashes with field of similar name from base class 'A'
comment:5 by , 14 years ago
Uh, seems like a bug to me, but the ORM isn't my strong field.. waiting for someone capable to review it.
comment:6 by , 14 years ago
Cc: | added |
---|
comment:7 by , 14 years ago
Just a note. The new feature suggested here would be in the same spirit as ModelForm.Meta.widgets
[1], which allows to override the widgets for given individual form fields instead of having to redefine the entire fields themselves. So, even if it were possible to override an entire Model
field, I think it would still be nice to be able to override certain field properties, like unique
for example.
I understand that we don't want to overload the Meta
options, but hopefully it would make sense in this case. I don't know enough about the ORM to predict if there could be bad side effects so I'm leaving it up to the ORM experts to decide ;-)
[1] http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-default-field-types-or-widgets
comment:8 by , 14 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
I'm -1 on this feature, it moves a field level option to the model level, which is wrong, also if the issue is inheritance solving just one special case is the complete wrong way to do this. Finally, a strong argument can be made that it's completely inappropriate to allow changing the field on subclasses (even in the abstract case, it obviously is in the MTI case). Marking as DDN for now, but I'm inclined to wontfix it.
comment:9 by , 14 years ago
That's fair enough. Thanks for your feedback. I'm not too precious about this and I won't mind if it gets wontfixed.
Just for the sake of argumentation, the case could also be made that the framework could allow the overriding of certain field properties at the Model
level, in the same way as, like noted above, a form field's widget
property can be overridden at the ModelForm
level. Purely as a convenience.
Also, I often see many of the constraints linked to model inheritance, like to one pointed out by this ticket, quite unfortunate as they drastically limit the possibilities of making apps reusable. In my case, it's a shame that the abstract class A
cannot be reused so easily in any context, where certain of its fields may or may not be unique. One approach would be to have the app ship some mixins A1
and A2
, both defining a blah
field but the former setting unique=False
and the latter unique=True
. But again, this would mean the app would have to anticipate every use case it might be used in, which again goes against the principles of reusability.
Anyway, for me this would be a nice-to-have feature rather than something essential. Maybe this is also highlighting some bigger issues with Django's handling of model inheritance and therefore should be part of a broader discussion.
comment:10 by , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
UI/UX: | unset |
I'm with Alex for most of the same reasons. Retrofitting the database level behaviour of a parent class feels a bit fragile. Model inheritance differs from Python class inheritance in a few ways and overriding is one of them. A field validator is probably one solution here.
The reuse argument doesn't convince me a lot, either. If the field is genuinely intended to be reused as unique, it should be marked as such. It's not really subclassing when it's both unique and non-unique in different situations -- it's attempting to reuse something of the same name in different context, not using "is-a" relationships.
(fixed description:
B
inherits fromA
)