I want to modify some fields in model form, and i found two methods:
First Method:
class ProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['bio'].widget.attrs.update({'placeholder': 'Enter your bio here'})
class Meta:
model = Profile
fields = ['bio']
Second Method:
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['bio']
widgets = {
'bio': Textarea(attrs={'placeholder': 'Enter your bio here'})
I just want to know if they are the same? Which is better? Or is there another better way?
Thankyou.
Method 1
The first method calls the constructor super().__init__(*args, **kwargs)
prior to manipulating the field. This enables developers to build the class in a default state and then play around with the classes components (attributes, functions).
The first method is most commonly used if the developer cannot achieve the results they want within the second method. This is because you're moving away from configuration to more of a manipulation of the class.
Method 2
The second method allows developers to define the configuration of the class before it is instantiated. This generally provides better usability and readability to other developers.
EXAMPLE:
Say you want your field bio
to be a required for all general users except for superusers.
class ProfileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop(user, None)
super().__init__(*args, **kwargs)
if self.user.is_superuser():
self.fields['bio'].required = False
class Meta:
model = Profile
fields = ['bio']
Using this method you can allow your Profile
model's bio
field attributes to be transposed to a form field upon instantiating and then making a small tweak to determine whether it's required for that particular user. This can be done without redefining the whole field.
Note: The form call in the GET request would look like
ProfileForm(user=request.user)