django-unicorn
django-unicorn copied to clipboard
How to pass a form from a template to a unicorn component.
I have been trying to pass a form from my template to a unicorn template
class UnicornCreateStudentFormView(UnicornView):
form = None
def __init__(self, form, *args, **kwargs):
super().__init__(*args, **kwargs)
print(form, type(form))
self.form = form
The component template
<div class="py-5">
{% load crispy_forms_tags %}
<style>
[unicorn\:error\:invalid] {
border: 1px solid red !important;
}
[unicorn\:error\:required] {
border: 1px solid red !important;
}
</style>
<form action="." method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<div class="col-12">
<div class="shadow p-3">
<div class="row ">
<div class="col-md-6">
<label for="id_username">Username:</label>
<input unicorn:model="username" class="form-control" type="text" name="username"
id="id_username" />
<span class="text-danger">{{ username_message }}</span>
</div>
<div class="col-md-6">
<label for="id_password">Password:</label>
<input unicorn:model="password" class="form-control" type="password" name="password"
id="id_password" />
<span class="text-danger">{{ password_message }}</span>
{{ form }}
</div>
</div>
</div>
</div>
<button unicorn:click="$validate">Validate</button>
</div>
</form>
</div>
I pass in the form as
{% unicorn 'unicorn-create-student-form' form=student_create_form %}
where student_create_form was passed into the template from the view context.
However the page displays the error
Request Method: | GET
-- | --
http://127.0.0.1:8000/administrator/student/create/
3.1.7
PicklingError
Can't pickle <function capfirst at 0x0000023A1F737678>: it's not the same object as django.utils.text.capfirst
C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django_unicorn\utils.py, line 55, in get_cacheable_component
C:\Users\user\Desktop\projects\school\venv\Scripts\python.exe
3.7.7
The terminal error is
maxlength="150" required id="id_username"><br><span class="helptext">Required. 150 characters
or fewer. Letters, digits and @/./+/-/_ only.</span></td></tr>
<tr><th><label for="id_email">Email address:</label></th><td><input type="email" name="email"
maxlength="254" id="id_email"></td></tr>
<tr><th><label for="id_first_name">First name:</label></th><td><input type="text" name="first_name" maxlength="200" required id="id_first_name"></td></tr>
<tr><th><label for="id_last_name">Last name:</label></th><td><input type="text" name="last_name" maxlength="200" required id="id_last_name"></td></tr>
<tr><th><label for="id_password">Password:</label></th><td><input type="password" name="password" required id="id_password"></td></tr>
<tr><th><label for="id_picture">Picture:</label></th><td><input type="file" name="picture" accept="image/*" id="id_picture"></td></tr> <class 'administrator.forms.StudentCreateForm'>
Internal Server Error: /administrator/student/create/
Traceback (most recent call last):
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:\Users\user\Desktop\projects\school\administrator\utils.py", line 7, in __inner__
return function(request, *args, **kwargs)
File "C:\Users\user\Desktop\projects\school\administrator\views.py", line 25, in create_student
return render(request, 'administrator/create_student.html', {'student_form': student_form})
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\shortcuts.py", line 19, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\loader.py", line 62, in render_to_string
return template.render(context, request)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 170, in render
return self._render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\test\utils.py", line 96, in instrumented_test_render
return self.nodelist.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\test\utils.py", line 96, in instrumented_test_render
return self.nodelist.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 938, in render
bit = node.render_annotated(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django\template\base.py", line 905, in render_annotated
return self.render(context)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django_unicorn\templatetags\unicorn.py", line 137, in render
request=request,
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django_unicorn\decorators.py", line 59, in timed
result = wrapped(*args, **kwargs)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django_unicorn\components\unicorn_view.py", line 742, in create
cacheable_component = get_cacheable_component(component)
File "C:\Users\user\Desktop\projects\school\venv\lib\site-packages\django_unicorn\utils.py", line 55, in get_cacheable_component
pickle.dumps(component)
_pickle.PicklingError: Can't pickle <function capfirst at 0x000001FD91EB7678>: it's not the same object as django.utils.text.capfirst
I have resorted to a different solution where I do not pass the form to a component. But j still think being able to pass the form would be great.
Hmm, I'm not sure what is going here. Can you post the form that has capfirst
? Unicorn
pickles components to keep state in cache for performance reasons. It will log a warning if it can't pickle the component, but everything should still "work".
But, I can check into it if I see the code. Thanks!
Rendering the form normally in a Django template works perfectly. And post it also
I see why it's breaking now. Unfortunately, I don't currently know how I would serialize/deserialize an instantiated form class although it might be possible. I'll let you know if I can figure out how to make it work!
I have resorted to a different solution where I do not pass the form to a component
Are you instantiating the form inside the component view init method, or something else?
I instantiated it in a regular Django view.
I think that is needed use javascript_exclude
when passing not serializables objects to unicorn.
I had a similar problem.
from django_unicorn.components import UnicornView
class CheckoutPaymentMethodView(UnicornView):
length = ''
class Meta:
exclude = ()
javascript_exclude = ('form', 'wizard')
Calling from html.
{% unicorn 'checkout/checkout_payment_method' form=form wizard=wizard %}