Django as_crispy_field doesn't render the TemporaryUploadedFile data - django

I have a Django formset that receives the POST request data once submitted, and it saves it (including the uploading file) normally to my database, but if the form is invalid, the page renders again with the same values but missing the selected uploaded file.
I am passing the data to the formset as:
fs = MyFormset(request.POST, request.FILES, .......)
and I am rendering the fields of each form one by one. So, the file field data is:
<div class="col-md-10">
{{ form.included_documents|as_crispy_field }}
</div>
When I submit a new form but it fails in one of the validation criteria, it returns with no file chosen although there was a file chosen. But, if I have a saved form, it renders the uploaded file normally.
Failed Tested Workaround:
According to this Github issue answer, I tested it and it parsed the file input with a better look, but it still fails with parsing the TemporaryUploadedFile.
To make sure that I have the value in my form, I added the below, and it showed the value correctly in the span element not the crispy field element:
<div class="col-md-10">
{{ form.included_documents|as_crispy_field }}
<span>{{ form.included_documents.value }}</span>
</div>
What am I missing here to render the TemporaryUploadedFile in crispy field?

Related

How can I render new HTML content in Django template?

I'm a beginner in Django.
In my template file, I have the following:
<select id="selectbox"></select>
<div id="containerdiv"></div>
Within the containerdiv, I can return a HttpResponse such as:
<form> <!-- some more input elements here --> </form>
so now I will have a new form within the div. The content of the form will change depending on the value of selectbox. However, I also have {% csrf_token %} tag within the rendered HttpResponse which is not being rendered properly. Is this even the correct way to work with Django?
You could load as many forms in the page by the following method
def formPage(request):
form1=FormA()
form2=FormB()
#as many as you want
return render(request,"example.html",{"form1"=form1,"form2":form2})
Then call the forms in the HTML pages as per the name specified in the view, and use vanilla JS to render form as per choice selected in the choice box
You can refer the following link: JS content manipulation

How can i add a "like" button in a Django class ListView

I am pulling my hair out trying to add a "like" button in my siteĀ“s post app, but as i want to add it in a ListView that contains the rest of the posts entries and everyone has the option to be commented I have added a Formixin to do so, so, now i cannot add another form for the like button as it would mean two posts requests....so I am not finding a clear solution... I have read here and there about using AJAX or Json techs but as im new programing im kind of stuck in it... has anyone any tip to offer?
While using AJAX (javascript XHR requests) would be the proper way so the page doesn't need to be refreshed when just clicking a like button, you can do it without AJAX.
HTML
On the HTML side of things, you can have multiple forms (<form>), one for each post, which have a hidden input field that's the post's id. You have set that explicitly in the HTML template, e.g.
{% for post in post_list %}
<h3>{{ post.title }}</h3>
<p>{{ post.summary }}</p>
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ post.id }}" name="{{ form.id.html_name }}">
<input type="submit">Like</input>
</form>
{% endfor %}
So basically you're reusing the form multiple times, changing the "value" attribute to match the post.
Django Form
Adding the FormMixin to your view is the right step, just use the form_class to a custom LikeForm with just one field that's an IntegerField called id.
View
By adding the FormMixin you get the form_valid() method, which you'll want to override to save the like:
def form_valid(self, form):
id = form.cleaned_data['id']
try:
post = Post.objects.get(id=id)
except Post.DoesNotExist:
raise Http404
post.likes.add(self.request.user) # assuming likes is a m2m relation to user
return redirect('post_list') # this list view
Hopefully I am not so late, I had similar challenges trying to implement the same functionalities on my website.
I came to realize that each button id should be unique (Preferably the post id if blog), but the classes can be the same.
I was able to solve it. Here is an article I wrote on medium recently on the steps I followed to so get this working you can check it out here

Django: The page shows "(<django.forms.fields.BooleanField object at ...>)" at variable location in a template

I was trying include a checkbox on my template, but it showed me some text on the browser instead.
I have a form (forms.py) that contains boolean field, e.g:
Class MyForm(forms.Form):
my_checkbox = forms.BooleanField(required=False, label='my_checkbox'),
and I have the following in my templates/my_app/my_form_template.py:
<form id="form" method="post">
{{ form.my_checkbox }}
<form>
In the browser after running the server, I've got:
(<django.forms.fields.BooleanField object at 0x0000014BE3CF9208>,)
The CharField and ChoiceField work perfectly except BooleanField. What is a way to represent a checkbox on the template?
I've tried {{ form }} in the template and it shows the checkbox, but I wish to custom the attributes of the checkbox.
There is a comma at the end of the field that causes an error. Removing it would fix the problem.

How to specify name of a Model Form's submit button name via django-webtest

I'm using django-webtest to automate functional tests for a Django application. One of my ModelForms has multiple submit buttons. The template, using django-crispy-forms, looks like this:
<form action="" method="post">
{% csrf_token %}
<p>
{{ person_form|crispy }}
<br><br>
{{ admin_form|crispy }}
</p>
<button id="SaveButton" type="submit" name="save_data" class="btn btn-lg btn-primary">Save</button>
<button id="VerifyButton" type="submit" name="verify_data" class="btn btn-lg btn-primary">Verify</button>
</form>
When I submit the form manually from the webpage by clicking on the Save button, the request.POST that is passed into the corresponding view method contains the 'save_data' tag that I use to decide what to do in the code.
However, when I create a django-webtest testcase to do the same, the 'save_data' tag is absent, even if I specify it in form.submit() as follows:
def test_schools_app_access_school_admin_record(self):
school_index = self.app.get(reverse('schools:school_index'),
user=self.school_admin)
assert self.school_name in school_index
school_page = school_index.click(self.school_name)
assert 'View School Administrator' in school_page
school_admin_page = school_page.click('View School Administrator')
person_form = school_admin_page.forms[1]
assert person_form['person-name'].value == self.school_admin_name
# TODO: Figure out how to pass name='save_data' while submitting
person_form['person-email'] = self.school_admin_email
response = person_form.submit(name='save_data', value='save')
# Verify that the field has been updated in the database
person = Person.objects.get(name=self.school_admin_name)
assert self.school_admin_email in person.email
How do I get django-webtest to include the name of the submit button in request.POST ?
Also, since I have multiple forms on the same page, I'm currently using response.forms[1] to select the form of interest. But I would like to use the form id instead. I couldn't locate in the Django documentation how to assign the form id (not field id) to a ModelForm. Could someone help me with this?
I'm using Django 1.7, django-webtest 1.7.8, WebTest 2.0.18 and django-crispy-forms 1.4.0.
I figured out that I'd made a typo in my code snippet because of which my code was not working.
In this fragment
person_form['person-email'] = self.school_admin_email
response = person_form.submit(name='save_data', value='save')
I should have value='Save' instead of 'save'.
With this corrected, the response does contain the name 'save_data'.

How do I get the value of a BoundField in a django template?

The built in as_html, as_ul, as_p methods on Django forms don't work for me, nor does the built in {{field}} rendering, so I'm trying to write a custom form rendering.
Here's what I have so far:
<input id="id_{{field.html_name}}"
type="text"
name="{{field.html_name}}"
placeholder="{{field.label}}" <!-- "placeholder" is really the only reason I need to do a custom implementation -->
value="{{ XXX }}" <!-- what goes here? -->
maxlength="30" />
The question is, what should go in the value attribute (marked XXX above)?
I've done some looking around and it doesn't appear that BoundField supports a value or data attribute. I'm using ModelForms if it matters
Assuming the field name is "username" and the form name is "user_form", there are two values:
1) Initial:
{{ user_form.initial.username }}
2) Bound:
{{ user_form.username.data }}
The value attribute landed in trunk in 2010. The patch shows how to retrieve the value using the form/data (not simple in a template unfortunately). There are some template tag code snippets in the ticket comments you may find useful.
I tried to find an answer for this question for several hours. The above answer didn't help me.
I found the solution here:
http://djangosnippets.org/snippets/2264/
You need to add new directory: /yourproject/yourapp/templatetags/
In /yourproject/yourapp/templatetags/ place 2 files:
__init__.py - empty file
field_value.py - with the following code:
from django import template
register = template.Library()
#register.simple_tag
def field_value(field):
""" returns field value """
return field.form.initial.get(field.name, '')
At the beginning of your template you nedd to add:
{% load field_value %}
Where you want to output a value of a field you need to add:
{% field_value form.field %}
Or if you already have a "field" variable, then just:
{% field_value field %}
For me it was a field with name "text" of an inline form, so I added the following code
{% field_value inline_admin_form.form.text %}