Django form displays form object as string - django

I've got a jqGrid that has a button to create a new row. Instead of the Django form that I expect to show up, it just brings up a dialog that says "< views.export_view.ExportTemplateForm instance at 0xb1b2beec>"
HTML:
<div id="add-template-form-div" style="display:none">
<form method="post" name="templateform" id="template-form" title="Template Details">
<table><tbody>
{{export_template_form}}
</tbody></table>
</form>
<div class="form_loading">Adding Template...</div>
<div class="form_error"></div>
<div>
view:
#set other variables
infoDict['export_template_form'] = ExportTemplateForm()
#infoDict gets passed into render_response
class ExportTemplateForm():
id = forms.CharField(widget=forms.HiddenInput())
class Meta(renderutils.BaseModelForm.Meta):
model = ExportTemplate
Any tips?

Related

'ManagementForm data is missing or has been tampered with' when submitting a form via XHR

I want a user to be able to select from an existing list of options. If the option is not within the ones already in the database, though, they need to be able to add a new item, while remaining on the main form, because after having added the new item they need to be able to save the main form
I was using the JQuery library select2, which allows a tags:True option, thanks to which users can add a new item to a list if not present. Nevertheless, Django validates that field and if it finds an item which is not in the database is raises an error. My initial plan was that of capturing the new value in the view and then (saving first the form with commit=False), if it was not in the database, save it. But this is not doable without forcing Django not to validate the field, which I haven't managed to do.
Another option, which I'm currently investigating, is that of adding a modal pop-up containing the sub-form. Of course I'd like to avoid opening the sub-form in another page, which would work but would be quite non-user-friendly.
models.py:
class Venue(models.Model):
venue_name = models.CharField(max_length=30)
class performanceOfCompositionNoDb(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.SET_NULL, null=True, blank=True)
forms.py:
class VenueForm(forms.ModelForm):
class Meta:
model = Venue
fields = ['venue_name']
views.py:
def composition_edit_view(request, id=id):
form_composition = CompositionForm(request.POST or None, instance=obj)
form_venue = VenueForm(request.POST or None)
if request.method == "POST" and form_composition.is_valid():
form_composition.save()
context = {
'form_composition': form_composition,
'form_venue': form_venue
[...]
def venue_add_view(request):
form_venue = VenueForm(request.POST or None)
if form_venue.is_valid():
form_venue.save()
context = {
'form_venue': form_venue,
}
return render(request, "venue-add.html", context)
my template.html:
{% include '../venue-add.html'%}
<form id="compositionForm" action='.' enctype="multipart/form-data" method='POST'>
{{form_composition}}
<p>Add new venue</p>
<input class="button" type='submit' id='save' value='Save' />
</form>
venue-add.html:
<div class="reveal" id="addvenueModal" data-reveal>
<form action='.' enctype="multipart/form-data" method='POST'>
{% csrf_token %}
<div class="grid-container">
<div class="grid-x grid-padding-x">
{{ form_venue }}
</div>
<input class="button" type='submit' value='Save' />
</div>
</form>
</div>
I'm expecting to open the venue-add form when I click on the 'Add new venue' button, which happens. With the modal open and the new text input, I then click the 'submit' button of the modal. At that point I get a 'Validation error - ['ManagementForm data is missing or has been tampered with']'. I have other formsets in the main template, and it all works correctly if I don't add a new venue.
How can I solve this? Also, if there's a way of using the select2 library and add a new venue in a more dynamic way, do let me know! Thanks.
Testing with XHR
Using XHR gives the same ['ManagementForm data is missing or has been tampered with'] error in the response:
<div class="reveal" id="addVenue" data-reveal>
<form id="addVenueForm" action='.' onsubmit="addVenue(this); return false;" enctype="multipart/form-data" method='POST'>
{% csrf_token %}
<div class="grid-container">
<div class="grid-x grid-padding-x">
{{ form_venue }}
</div>
<input class="button" type='submit' value='Save' />
</div>
</form>
<script type="text/javascript"> "use strict";
function addVenue (oFormElement) {
var oReq = new XMLHttpRequest();
var data = new FormData(oFormElement)
oReq.onload = {}
oReq.onreadystatechange = function() {
if (oReq.readyState == XMLHttpRequest.DONE) {
var result = oReq.responseText;}
}
oReq.open("post", oFormElement.action, true);
oReq.send(data);
} </script>
As I said, I do have formsets (working correctly) in the main form from which I'm launching this modal. This modal doesn't contain any formset though, it's a simple one-field form, with its own csrf token.
Edit 2
OK, so upon further investigating I've found that the error springs from
return render(request, "compositions/composition_edit.html", context)
in the view.py. In other words, when I hit 'submit' in the modal, for some reason the 'submit' of the main form kicks in also, thus generating issues. How can I isolate the 'submit' of the modal and get the 'submit' of the main form not to kick in unless explicitly clicked?
I had to change the action of the modal form to the address I mapped in my urls.py (action='/venue-add/') for that form. That solved the issue.
Now, the newly-added items are not displayed in the main form unless I refresh the page, no matter ho many times I destroy/empty/repopulate the select2() dropdown list. I think this has to do with the fact that the data to the venue dropdown list is sent by the view at the loading of the main form, and that the context remains the same no matter what updates to the database have been made after the page loading.
For the above reason I'm investigating using an API on my own application and GET and POST data via an AJAX call, which still gives me issue. I'm opening another question for that though.

Send JSON from Places Autocomplete to Flask

I'm working on my very first web app utilizing the Google Places Autocomplete functionality in the frontend and Flask in the backend.
Current situation:
Whenever an address is selected from the autocomplete suggestions, a variable called 'address' is populated in the background containing the API response as JSON. Using a window alert I can confirm that this part works fine.
To-Do/ issue:
The address variable should be sent over to Flask so that I can do use it going forward.
Using AJAX to post the data however it never seems to reach Flask. The output is always None.
My best guess is that the submit button implemented after the Autocomplete stuff somehow overrides the JSON POST data in order to keep only the actual text which is in the form while submitting*.
Does that make sense? If yes, how can I still send the JSON data successfully? Or is the issue somewhere else?
I would appreciate any help.
Here is my code:
home.html
{% extends "base.html" %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block app_content %}
{% from "_formhelpers.html" import render_field %}
<div class="container">
<form class="form form-horizontal" action="" method="post" role="form" novalidate>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=key&libraries=places&language=en"></script>
<script type="text/javascript">
google.maps.event.addDomListener(window, 'load', function () {
var autocomplete = new google.maps.places.Autocomplete(document.getElementById('autocomplete'),{
types: ['geocode']
});
// autocomplete.setFields('address_components');
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
var address = place.address_components;
window.alert(JSON.stringify(address));
}
)})
$.ajax({
type: "POST",
url: "/",
data: address,
success: function(){},
dataType: "json",
contentType : "application/json"
});
</script>
<input type="text" id="autocomplete" size=50 style="width: 250px" placeholder="Enter your location" name=inputkiez>
<a href=# id=autocomplete><button class='btn btn-default'>Submit</button></a>
</form>
<div class="row">
or check out <a href='/result'> the latest reviews from others </a>
<div>
</div>
{% endblock %}
routes.py
#app.route('/', methods=['GET','POST'])
def search():
if request.method == 'POST':
jsdata = request.get_json()
flash('Data is: {}'.format(jsdata))
return redirect('/review')
return render_template('home.html')
#app.route('/review', methods=['GET', 'POST'])
def review():
reviewform = ReviewForm()
if reviewform.validate_on_submit():
userreview = Reviews(
reviewcriteria1= reviewform.reviewcriteria1.data,
reviewcriteria2= reviewform.reviewcriteria2.data,
reviewcriteria3= reviewform.reviewcriteria3.data,
)
db.session.add(userreview)
db.session.commit()
return redirect('/result')
return render_template('review.html', form=reviewform)
*The text in the form would include the address selected from Autocomplete but without any additional data obviously. I even managed to pass this text to the next page with request.form.to_dict() but this is not good enough for my use case since I also want at least the postal code to be sent over.
This is not the exact answer to my question but I found a way to send over the data to flask without having to bring in JSON/AJAX at all.
The trick is to send the data from the Autoplaces response as a hidden input of the form:
<form method="post" action="">
<input id="userinput" placeholder="Enter a location" type="text" name="name" class="form-control"><br>
<div id="map" style="height: 300px;width: 300px; float: none; margin: 0 auto;"></div><br>
<input type="hidden" name="address" id="address">
<input type="submit" name="submit" value="Submit" class="form-control btn btn-primary">
<div>or check out <a href='/result'> the latest reviews from others </a></div>
</form>
Then in routes.py you can easily get the data like this:
#app.route('/', methods=['GET','POST'])
def search():
if request.method == 'POST':
address = request.form['address']
# do something
This is basically a slightly modified version of the solution posted here (YT video).

django python form to submit, delete row from database and refresh page

I am newbie in Django and I would appreciate if someone can help me about this problem.
I have a database in backend with 100 rows of users information.
Name, surname, phone number.
The database is visible on Home page template and if you choose one of this names you can donate something to this person.
When you click on submit button will lead you to new ajax window where you input your data and then submit.
Then I got your message on email.
My questions is how to do at the same time to confirm (submit) and delete row from database (person from database) and then to refresh page ?
Meaning, when you submit form then function should delete person from Home page at once and have to refresh page so you can see another person ?
Here is the code.
I would appreciate any help.
Thanks to all.
views.py
def about(request):
context = {
'num_toys': '1',
}
return render(request, 'about.html') # , context=context
def couses(request):
db_queryset = Children.objects.all()
context = {'child': db_queryset}
return render(request, 'couses.html', context=context)
class ChildrenListView(ListView):
model = Children
context_object_name = 'child'
class ChildrenCreateView(CreateView):
model = Children
form_class = ChildrenForm
success_url = reverse_lazy('children_changelist')
class ChildrenUpdateView(UpdateView):
model = Children
form_class = ChildrenForm
success_url = reverse_lazy('children_changelist')
class ChildrenDetailView(DetailView):
model = Children
form_class = ChildrenForm
success_url = reverse_lazy('children_detail')
children_detail.html
<!-- Start contact form area -->
<div class="couses">
<section class="contact-form-area pb-60 pt-90">
<div class="couses">
<div class="container">
<div class="row">
<!-- Start section title -->
<div class="col-sm-12">
<div class="section-title text-center">
<h2>Donate <span> {{ children.toy }} </span> to <span>{{ children.name }}</span> who is <span>{{children.date }} old</span></h2>
<img src="static/children/img/title-bottom.png" alt="">
</div>
</div>
<!-- End section title -->
<div class="col-sm-12">
<div class="contact-form">
<form id="contact-form" method="POST" action="mail.php">
<div class="form-fields">
<label for="name">Name</label>
<input id="name" name="name" type="text" placeholder="Your Name" required>
</div>
<div class="form-fields">
<label for="email">Email</label>
<input id="email" name="email" type="text" placeholder="Your Email" required>
</div>
<div class="form-fields last">
<label for="phone">Phone</label>
<input id="phone" name="phone" type="text" placeholder="Your Phone" required>
</div>
<div class="message-fields">
<label for="mess">Message</label>
<textarea name="mess" id="mess" cols="30" rows="10" placeholder="Message"></textarea>
</div>
<div class="form-button">
<button type="submit">Send your message</button>
<button type="reset">Reset</button>
</div>
</form>
<p class="form-messege"></p>
</div>
</div>
</div>
</div>
</div>
</section>
sorry if I'm wrong but I understand that you want to do two actions.
In your code I can see that you have forms and class-based Views. Maybe you need to override the function form_valid to do the operations you need when you submit.
Check this website http://ccbv.co.uk there you will find the details of the views.
On click of submit hit the url & process your message on email part first and then you can delete the person from database by filtering out object of that particular person with whatever primary key you have for that table by writing a query in your view. and then render the remaining data of that table to your template on which you are Redirecting from your on submit click.
From above conversation what i understood that you don't want delete that person from database boolean field would be great option rather you want to save the message that has been sent from email by this way you can do both at the same time. you have the message saved in your database and from empty message data can render those user on template.

Django Responsive Form using class:'form-control'

I have a from and added a bootstrap class':'form-control' to every field of the form to make them responsive like this :
companyname=forms.CharField( widget=forms.PasswordInput(attrs={'class':'form-control' ,'style': 'width:30%'}) )
but when i add form-control class , the label is showd at the upper row of the text box
i dont know what to do to bring the label beside the text box
when it has no class the code below is ok but its not responsive
<div class="panel-body" style="text-align:right ; margin-left:auto;margin-right:auto;width:80%;">
<div style="width:85% ;margin-left:auto;margin-right:auto;">
<form enctype="multipart/form-data" method="post" >
{% csrf_token %}
{{ profile_form.as_p}}
<input id="savepersonalinfo" type="submit" name="" value="ثبت">
</form>
</div>
</div>
and also how can i put the textboxes arranged exactly in same column ?
in the picutre iust companyname has form-control class and is responsive and other fields are not

Existing forms:In Django

I have an pre-built HTML form and I need to reuse it with Django form class (django.forms), So how do I incorporate my HTML form with Django form class. for example
HTML:
<li id="foli11" class="">
<label class="desc" id="title11" for="Field11">
Username
<span id="req_0" class="req">*</span>
</label>
<div class="col">
<input id="Field11" name="Field11" type="text" class="field text medium" value="" maxlength="255" tabindex="11" />
</div>
</li>
How do I map this HTML in to Django form class, I know that it can be done by modifying Django form fields according to this HTML. But I guess it's a time consuming approach,so I would like to know that is there any easy and time saving solutions for this issue.
Thanks.
Extend the django forms.Form class and write to it your own form.as_my_ul similar to form.as_p:
Here is the implementation of as_p: http://code.djangoproject.com/browser/django/trunk/django/forms/forms.py#L227
def as_p(self):
"Returns this form rendered as HTML <p>s."
return self._html_output(
normal_row = u'<p%(html_class_attr)s>%(label)s %(field)s%(help_text)s</p>',
error_row = u'%s',
row_ender = '</p>',
help_text_html = u' %s',
errors_on_separate_row = True)