The main difference between the two is that in forms that are created from forms. ModelForm , we have to declare which model will be used to create our form. In our Article Form above we have this line " model = models. Article " which basically means we are going to use Article model to create our form.
To create ModelForm in django, you need to specify fields. Just associate the fields to first_name and lastName. Under the Meta class you can add : fields = ['first_name','lastName']. @Shishir solution works after I add that line. or you can try solution in Jihoon answers by adding vacant fields.
Django ModelForm is a class that is used to directly convert a model into a Django form. If you're building a database-driven app, chances are you'll have forms that map closely to Django models. For example, a User Registration model and form would have the same quality and quantity of model fields and form fields.
The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.
The easiest way for your use case is to use CSS. It's a language meant for defining presentation. Look at the code generated by form, take note of the ids for fields that interest you, and change appearance of these fields through CSS.
Example for long_desc
field in your ProductForm (when your form does not have a custom prefix):
#id_long_desc {
width: 300px;
height: 200px;
}
Second approach is to pass the attrs
keyword to your widget constructor.
class ProductForm(ModelForm):
long_desc = forms.CharField(widget=forms.Textarea(attrs={'cols': 10, 'rows': 20}))
short_desc = forms.CharField(widget=forms.Textarea)
class Meta:
model = Product
It's described in Django documentation.
Third approach is to leave the nice declarative interface of newforms for a while and set your widget attributes in custom constructor.
class ProductForm(ModelForm):
long_desc = forms.CharField(widget=forms.Textarea)
short_desc = forms.CharField(widget=forms.Textarea)
class Meta:
model = Product
# Edit by bryan
def __init__(self, *args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
self.fields['long_desc'].widget.attrs['cols'] = 10
self.fields['long_desc'].widget.attrs['rows'] = 20
This approach has the following advantages:
Excellent answer by zuber, but I believe there's an error in the example code for the third approach. The constructor should be:
def __init__(self, *args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
self.fields['long_desc'].widget.attrs['cols'] = 10
self.fields['long_desc'].widget.attrs['cols'] = 20
The Field objects have no 'attrs' attributes, but their widgets do.
In the event that you're using an add-on like Grappelli that makes heavy use of styles, you may find that any overridden row and col attributes get ignored because of CSS selectors acting on your widget. This could happen when using zuber's excellent Second or Third approach above.
In this case, simply use the First Approach blended with either the Second or Third Approach by setting a 'style' attribute instead of the 'rows' and 'cols' attributes.
Here's an example modifying init in the Third Approach above:
def __init__(self, *args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
self.fields['short_desc'].widget.attrs['style'] = 'width:400px; height:40px;'
self.fields['long_desc'].widget.attrs['style'] = 'width:800px; height:80px;'
Set row and your css class in your admin model view:
'explicacion': AutosizedTextarea(attrs={'rows': 5, 'class': 'input-xxlarge', 'style': 'width: 99% !important; resize: vertical !important;'}),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With