18👍
No, that won’t work. Meta is parsed by – surprisingly – the metaclass, before you even get to __init__
.
The way to do this is to add the field manually to self.fields
:
def __init__(self, *args, **kwargs):
super(PartialAuthorForm, self).__init__(*args, **kwargs)
self.fields['year'] = forms.CharField(whatever)
16👍
The answers from others are are great (especially @BranHandley’s), but sometimes, its easiest to conditionally remove something instead. Obviously this doesn’t work with things that are dynamically created, but if you only need to optionally include a field or not, then try it like this.
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = ['normalField', 'conditionalField', ]
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
if condition is True:
del self.fields['conditionalField']
Doing it the other way can be rather complicated as pointed out above, but dropping it conditionally is pretty straight forward. =)
4👍
The answers that say to use __init__
will work but you lose the connection to the model (assuming that the field you are adding is on the model). Instead you can make a new form dynamically that inherits from the existing form.
def my_form_factory:
class ModifiedAuthorForm(PartialAuthorForm):
class Meta(PartialAuthorForm.Meta):
fields = PartialAuthorForm.Meta.fields
if hasattr(fields, 'append'):
fields.append('year')
else:
fields = fields + ('year',)
return ModifiedAuthorForm
Of course if you want to be robust you should probably check that the field you are adding isn’t already in fields
and you should probably handle exclude
as well.
- Django: how to change values for nullbooleanfield in a modelform?
- When to use NullBooleanField in Django
- "TemplateSyntaxError Invalid block tag: 'trans'" error in Django Templates
1👍
Adding field to model form by overriding form’s __init__ method will not work as model form fields are initialized before form constructor call. So you won’t get any values from actual model to the form and your values will not be saved to db after save call.
You need to use full beauty of python and use class decorator like this 😉
def year_decorator(form_class):
class ModifiedForm(form_class):
class Meta(form_class.Meta):
if isinstance(form_class.Meta.model, Author):
fields = form_class.Meta.fields + ('year',)
return ModifiedForm
@year_decorator
class PartialAuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title')
- Making Twitter, Tastypie, Django, XAuth and iOS work to Build Django-based Access Permissions
- Add functionality to Django FlatPages without changing the original Django App
0👍
The inner Meta
class is already processed when the ModelForm class is created through a metaclass, which is BEFORE an instance is created. Doing what you ware trying to do in __init__
will not work like that!
You can access the created field objects in a dictonary self.fields
eg. you can do something like self.fields['year'] = forms.MyFormField(...)
.
- How do you create a Django HttpRequest object with the META fields populated?
- Django-admin.py startproject opens notepad, instead of creating a project
- How do I hide the field label for a HiddenInput widget in Django Admin?