django-bootstrap3 Parameter "field" should contain a valid Django BoundField?
Question:
I am using django-bootstrap3 to render my forms on the template and i have been struggling to find what is causing the error Parameter "field" should contain a valid Django BoundField
when i try to load the page with the form on it. I have attached my code and error below. can someone please point for me what i’m doing wrong?
forms.py
class OrderForm(forms.Form):
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
email = forms. EmailField(max_length=50)
institution_name = forms.CharField(max_length=150)
phone = forms.IntegerField()
address = forms.CharField(max_length=100)
city = forms.CharField(max_length=50)
item = forms.CharField(max_length=100)
serial_number = forms.CharField(max_length=50)
problem = forms.CharField(widget=forms.Textarea(attrs—Crows':10,'cols':18,'style':'resize:none', [placeholder':'Please define your problem here'l),label='Problem description')
[placeholder':'Please define your problem here'l),label='Problem description')
views.py
def Orderview(request):
if request.method == 'Post':
order_form = OrderForm(request.POST)
if order_form.is_valid():
cd = order form.cleaned data
subject = '{} repair order from {}'.format(cd['item'],cd['institution_name'])
from_email = cd['email']
to = [settings.EMAIL_HOST_USER,]
ctx = {
'first_name':cd['first_name'],
'last_name':cd['last_name'],
'email':cd['email'],
'institution_name':cd['institution_name'],
'phone':cd['phone'],
'address':cd['address'],
'city':cd['city'],
'item':cd['item'],
'serial_number.:cd['serial_number'],
'problem':cd['problem'],
}
message = get_template('electroapp/email/order.html').render(Context(ctx))
msg = EmailMessage(subject,message,to=to,from_email=from_email)
msg.content_subtype='html'
msg.send()
messages.success(request,' Your Repair order has been sent',)
return redirect('electroapp:repair_order')
else:
order_form = OrderForm()
return render(request,'electroapp/orderform.html',{'Order_form':order_form})
Answers:
This could be because some fields may be missing.Take a look at this
You could do something like this to see what fields are available:
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form order_form %}
{% buttons submit='OK' reset="Cancel" %}{% endbuttons %}
</form>
and then try to figure out why you are having missing fields.
Parameter "field" should contain a valid Django BoundField
Why can't they just tell us which actual field? Well, here's how I solved it.
A little debugging and you'll find this is thrown within renderers.py:
class FieldRenderer(BaseRenderer):
"""Default field renderer."""
# These widgets will not be wrapped in a form-control class
WIDGETS_NO_FORM_CONTROL = (CheckboxInput, RadioSelect, CheckboxSelectMultiple, FileInput)
def __init__(self, field, *args, **kwargs):
if not isinstance(field, BoundField):
raise BootstrapError('Parameter "field" should contain a valid Django BoundField.')
self.field = field
super().__init__(*args, **kwargs) ...
The message is not helpful, but can be fixed in your dev/test environment.
WARNING: The following will void your warranty! 🙂
Go up a few steps in the render chain in library.py (for example ~/.virtualenvs/your_env/lib/python3.8/site/packages/django/template/library.py)
and find SimpleNode.
class SimpleNode(TagHelperNode):
def __init__(self, func, takes_context, args, kwargs, target_var):
super().__init__(func, takes_context, args, kwargs)
self.target_var = target_var
def render(self, context):
resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
output = self.func(*resolved_args, **resolved_kwargs)
if self.target_var is not None:
context[self.target_var] = output
return ''
if context.autoescape:
output = conditional_escape(output)
return output
After copying the original file to a backup, change it as follows. We are wrapping the line
output = self.func(*resolved_args, **resolved_kwargs)
with a try/except. Here's the result:
class SimpleNode(TagHelperNode):
def __init__(self, func, takes_context, args, kwargs, target_var):
super().__init__(func, takes_context, args, kwargs)
self.target_var = target_var
def render(self, context):
resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
###
from bootstrap3.exceptions import BootstrapError
try:
output = self.func(*resolved_args, **resolved_kwargs)
except BootstrapError as b:
raise BootstrapError(str(b).replace('"field"', self.args[0].token)) from b
###
if self.target_var is not None:
context[self.target_var] = output
return ''
if context.autoescape:
output = conditional_escape(output)
return output
Within the SimpleNode class we have access to the name of the field that couldn't be rendered. So we intercept the exception there and re-throw it with the useful tidbit injected. Voila, you will now get an exception report that tells you the actual problem field.
Cheers.
I am using django-bootstrap3 to render my forms on the template and i have been struggling to find what is causing the error Parameter "field" should contain a valid Django BoundField
when i try to load the page with the form on it. I have attached my code and error below. can someone please point for me what i’m doing wrong?
forms.py
class OrderForm(forms.Form):
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
email = forms. EmailField(max_length=50)
institution_name = forms.CharField(max_length=150)
phone = forms.IntegerField()
address = forms.CharField(max_length=100)
city = forms.CharField(max_length=50)
item = forms.CharField(max_length=100)
serial_number = forms.CharField(max_length=50)
problem = forms.CharField(widget=forms.Textarea(attrs—Crows':10,'cols':18,'style':'resize:none', [placeholder':'Please define your problem here'l),label='Problem description')
[placeholder':'Please define your problem here'l),label='Problem description')
views.py
def Orderview(request):
if request.method == 'Post':
order_form = OrderForm(request.POST)
if order_form.is_valid():
cd = order form.cleaned data
subject = '{} repair order from {}'.format(cd['item'],cd['institution_name'])
from_email = cd['email']
to = [settings.EMAIL_HOST_USER,]
ctx = {
'first_name':cd['first_name'],
'last_name':cd['last_name'],
'email':cd['email'],
'institution_name':cd['institution_name'],
'phone':cd['phone'],
'address':cd['address'],
'city':cd['city'],
'item':cd['item'],
'serial_number.:cd['serial_number'],
'problem':cd['problem'],
}
message = get_template('electroapp/email/order.html').render(Context(ctx))
msg = EmailMessage(subject,message,to=to,from_email=from_email)
msg.content_subtype='html'
msg.send()
messages.success(request,' Your Repair order has been sent',)
return redirect('electroapp:repair_order')
else:
order_form = OrderForm()
return render(request,'electroapp/orderform.html',{'Order_form':order_form})
This could be because some fields may be missing.Take a look at this
You could do something like this to see what fields are available:
<form role="form" method="post">
{% csrf_token %}
{% bootstrap_form order_form %}
{% buttons submit='OK' reset="Cancel" %}{% endbuttons %}
</form>
and then try to figure out why you are having missing fields.
Parameter "field" should contain a valid Django BoundField
Why can't they just tell us which actual field? Well, here's how I solved it.
A little debugging and you'll find this is thrown within renderers.py:
class FieldRenderer(BaseRenderer):
"""Default field renderer."""
# These widgets will not be wrapped in a form-control class
WIDGETS_NO_FORM_CONTROL = (CheckboxInput, RadioSelect, CheckboxSelectMultiple, FileInput)
def __init__(self, field, *args, **kwargs):
if not isinstance(field, BoundField):
raise BootstrapError('Parameter "field" should contain a valid Django BoundField.')
self.field = field
super().__init__(*args, **kwargs) ...
The message is not helpful, but can be fixed in your dev/test environment.
WARNING: The following will void your warranty! 🙂
Go up a few steps in the render chain in library.py (for example ~/.virtualenvs/your_env/lib/python3.8/site/packages/django/template/library.py)
and find SimpleNode.
class SimpleNode(TagHelperNode):
def __init__(self, func, takes_context, args, kwargs, target_var):
super().__init__(func, takes_context, args, kwargs)
self.target_var = target_var
def render(self, context):
resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
output = self.func(*resolved_args, **resolved_kwargs)
if self.target_var is not None:
context[self.target_var] = output
return ''
if context.autoescape:
output = conditional_escape(output)
return output
After copying the original file to a backup, change it as follows. We are wrapping the line
output = self.func(*resolved_args, **resolved_kwargs)
with a try/except. Here's the result:
class SimpleNode(TagHelperNode):
def __init__(self, func, takes_context, args, kwargs, target_var):
super().__init__(func, takes_context, args, kwargs)
self.target_var = target_var
def render(self, context):
resolved_args, resolved_kwargs = self.get_resolved_arguments(context)
###
from bootstrap3.exceptions import BootstrapError
try:
output = self.func(*resolved_args, **resolved_kwargs)
except BootstrapError as b:
raise BootstrapError(str(b).replace('"field"', self.args[0].token)) from b
###
if self.target_var is not None:
context[self.target_var] = output
return ''
if context.autoescape:
output = conditional_escape(output)
return output
Within the SimpleNode class we have access to the name of the field that couldn't be rendered. So we intercept the exception there and re-throw it with the useful tidbit injected. Voila, you will now get an exception report that tells you the actual problem field.
Cheers.