2

I want to alter properties of a model field inherited from a base class. The way I try this below does not seem to have any effect. Any ideas?

def __init__(self, *args, **kwargs):
    super(SomeModel, self).__init__(*args, **kwargs)
    f = self._meta.get_field('some_field')
    f.blank = True
    f.help_text = 'This is optional'
Sam
  • 491
  • 1
  • 4
  • 16
  • why aren't you just overriding the field? why do all this? – S.Lott Dec 21 '09 at 16:00
  • I thought that redefining a field raises a django.core.exceptions.FieldError? (Local field foo ... clashes with field of similar name from base class) Am I missing something? – Sam Dec 21 '09 at 16:27
  • From the manual: "Django will raise a FieldError exception if you override any model field in any ancestor model." http://docs.djangoproject.com/en/dev/topics/db/models/ – Sam Dec 21 '09 at 16:33
  • So it sounds like you are inheriting from a concrete models.Model class and not an Abstract Base Class, correct? – Peter Rowell Dec 21 '09 at 16:37
  • No, I have my own base class AbstractArticle, the subclass of which should handle some fields a bit differently. – Sam Dec 21 '09 at 20:49
  • Another valid use would be: Populating field's choices with elements that can't be used during init phase. – Sam Dec 21 '09 at 22:41
  • Yet another use: I'm currently trying to use django-logicaldelete (https://github.com/paltman/django-logicaldelete) on a legacy database but can't because the field name isn't `date_removed`, it's `date_deleted`. Django won't let me change the `db_column` attribute for that field, so basically I either have to fork my own version of logicaldelete or not use it at all. – Jordan Reiter Mar 03 '11 at 18:32
  • If you need/can change properties of the underlying model, not just of the form itself, there is already an answer here: http://stackoverflow.com/a/6379556/170918 – Mr. Napik Jul 22 '16 at 09:15

2 Answers2

3

So.. You need to change blank and help_text attributes.. And I assume that you want this feature just so the help_text is displayed in forms, and form does not raise "this field is required"

So do this in forms:

class MyForm(ModelForm):
   class Meta:
      model = YourModel

   some_field = forms.CharField(required=False, help_text="Whatever you want")
Djangonaut
  • 5,511
  • 7
  • 40
  • 53
0

OK, that's simply not possible, here is why:

http://docs.djangoproject.com/en/1.1/topics/db/models/#field-name-hiding-is-not-permitted

EDIT: And by the way: don't try to change class properties inside a constructor, it's not a wise thing to do. Basically what you are trying to do, is to change the table, when you are creating a row. You wouldn't do that, if you were just using SQL, would you :)? Completely different thing is changing forms that way - I often dynamically change instance a form, but then I still change only this one instance, not the whole template (a class) of form to be used (for example to dynamically add a field, that is required in this instance of a form).

gruszczy
  • 40,948
  • 31
  • 128
  • 181
  • It seems that abstract = True is exactly what I was looking for. However, in your example, I think you meant to sublass A. class B(A) Which leads to exactly the same error. – Sam Dec 22 '09 at 10:49
  • Yeah, this is what I meant to do. It raises an exception? I will take a look at it, when I get access to my dev machine. – gruszczy Dec 23 '09 at 11:41
  • I have added a link, that should interest you. – gruszczy Dec 23 '09 at 17:28