Reputation: 986
I am very new to Django. Following some tutorials I have managed to create a form using the Python Generic Views (CreateView)
I have a 'Question' Model
class Question(models.Model):
title = models.CharField(max_length=200)
body = models.TextField(max_length=2000)
category = models.CharField(max_length=50)
votes = models.IntegerField(default=0)
asked_date = models.DateTimeField(default=datetime.now)
and using this model I have created a View Class
class QuestionCreate(CreateView):
model = Question
fields = ['title', 'body', 'category']
This does generate a nice HTML form. But how do I pass CSS attributes to each field?
Upvotes: 5
Views: 6744
Reputation: 9235
You could write a model form for Question and pass it to the create view,
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ('myfield1', 'myfield2)
widgets = {
'myfield1': forms.TextInput(attrs={'class': 'myfieldclass'}),
}
or you could override init method for specifying a certain class for every field,
def __init__(self, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
self.fields['myfield1'].widget.attrs.update({'class' : 'myfieldclass'})
Then, pass it to the attribute form_class
of CreateView
,
class QuestionCreate(CreateView):
model = Question
form_class = QuestionForm
Upvotes: 13
Reputation: 448
The best way is to override the get_form
function.
class QuestionCreate(CreateView):
model = Question
fields = ['title', 'body', 'category', 'MyField']
def get_form(self, form_class=None):
form = super(QuestionCreate, self).get_form(form_class)
form['MyField'].field.widget.attrs.update({'class' : 'MyClass'})
return form
Or if you want to add the attribute to all fields you can use a for-loop as follows:
class QuestionCreate(CreateView):
model = Question
fields = ['title', 'body', 'category', 'MyField']
def get_form(self, form_class=None):
form = super(OPCCreateView, self).get_form(form_class)
for visible in form.visible_fields():
visible.field.widget.attrs.update({'class' : 'MyClass'})
return form
Upvotes: 2
Reputation: 2526
I had a similar problem in my Django application based on the Bootstrap framework. My first attempt:
# views.py
from django.views.generic.edit import UpdateView
from . import models
class ModuleUpdateView(UpdateView):
model = models.Module
fields = ['name', 'description', 'status']
looked as follow:
Not very nice indeed! The second attempt implied defining a custom ModelForm for my view and applying all the customisations therein:
# forms.py
from .models import Module
class ModuleForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ModuleForm, self).__init__(*args, **kwargs)
for visible in self.visible_fields():
visible.field.widget.attrs['class'] = 'form-control'
class Meta:
model = Module
fields = ['name', 'description', 'status']
Please note the for cycle in __init__
, which adds the form-control CSS class to all visible form fields. The CSS styling for form-control is provided by Bootstrap so I didn't even have to modify my stylesheets.
Once I have my custom ModelForm I can rewrite my View class as follows:
# views.py
from django.views.generic.edit import UpdateView
from . import forms, models
class ModuleUpdateView(UpdateView):
model = models.Module
form_class = forms.ModuleForm
and you can see the results below.
Far better!
Hope that helps, feel free to comment in case of questions.
Upvotes: 7
Reputation: 1
We can use django-crispy-forms if we want some bootstrap styling to the rendered form:
pip install django-crispy-forms
Then add 'crispy-forms' to the installed apps.
Load the crispy_form_tags in the form template page and instead of {{form}} use {{form|crispy}}.
Documentation of Crispy.
Upvotes: 0
Reputation: 27513
class FooForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(FooForm, self).__init__(*args, **kwargs)
self.fields['field1'].widget.attrs = { 'class': 'fooclass' }
class Meta:
model = FooModel
fields = ['field1', 'field2']
you cannot directly add css
to the CreateView
for that you need to create a ModelForm
and use the form_class = FooForm
in your create view, and in this ModelForm
you can use specific class for the fields and use css to style them as needed
Upvotes: 4