I have a Django input slider defined as follows:
#widgets.py
from django.forms.widgets import NumberInput
class RangeInput(NumberInput):
input_type = 'range'
#forms.py
from polls.widgets import RangeInput
class VoteForm(forms.ModelForm):
class Meta:
#model = CC_Responses
model = CC_Resp_NoFK
fields = ['Person_ID', 'Test_date', 'Response_value']
# following added from SliderModelForm
widgets ={
'Response_value':RangeInput
}
which is “processed” by the view
def p2vote(request,q_id):
CC_question = get_object_or_404(CC_Questions, pk=q_id)
#
if request.method == 'POST':
form = VoteForm(request.POST)
if form.is_valid():
item = form.save(commit=False)
item.Q_ID = q_id
item.save()
return redirect('/polls/p2')
else:
formV = VoteForm()
return render(request, 'pollapp2/vote.html', {'var_name':CC_question,'form' : VoteForm()})
and in the template I have the inline CSS
<style>
/* Following CSS is used by the input slider (range) since Django assigns id value of id_Response_value */
/*See: https://stackoverflow.com/questions/110378/change-the-width-of-form-elements-created-with-modelform-in-django */
#id_Response_value{width:300px;}
</style>
which is associated with the slider/range
<label for="Response_value">Response value</label>
{% render_field form.Response_value rows="1" class="form-control" %}
I obtained id_Response_value by looking at the source of the rendered HTML in the browser – I guess I could explicitly set an ID. All the above works exactly as I want. I can control the width of the range slider using CSS.
Now, I believe, inline CSS is a “bad thing”, so as a step to improve my code I’m trying to associate the attribute “more directly” with the slider.
In Django documentation in the section: https://docs.djangoproject.com/en/4.0/topics/forms/modelforms/#overriding-the-default-fields
there is the following example:
from django.forms import ModelForm, Textarea
from myapp.models import Author
class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ('name', 'title', 'birth_date')
widgets = {
'name': Textarea(attrs={'cols': 80, 'rows': 20}),
}
The dictionary attrs created looks like it has CSS “stuff” in it, so I coded in widgets in the model form in forms.py
from polls.widgets import RangeInput
class VoteForm(forms.ModelForm):
class Meta:
model = CC_Resp_NoFK
fields = ['Person_ID', 'Test_date', 'Response_value']
widgets ={
'Response_value':RangeInput(attrs={'width': '1000px'}),
}
I tried both:
attrs={'width': '1000px'}
and
attrs={'width': 1000}
Neither changed the width of the range slider. Is what I am doing possible in the (model)form? Have I just got a problem with what I am coding in attrs?
I may have misunderstood but I see something like the following promoted as what needs to go in the ModelForm
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
No. Really? To change the attributes?