Django: ajax & request - ajax

I don`t speak english well? but i have problem in Django.
I have models:
class Model1(models.Model):
model2 = models.ManyToManyField(Model2)
#...
class Model2(models.Model):
model3 = models.ForeignKey(Model3)
#...
class Model3(models.Model):
custom = models.CharField()
have view
def simple(request, simple_id):
if request.method == 'POST':
if request.is_ajax():
if 'delete' in request.POST:
id3 = request.POST.get('delete', '')
Model1.objects.get(id = simple_id).model2.filter(model3__id = id3).delete()
That is, when submitting a form with name = "delete" Ajax have removed all the objects belonging to Model2 with the same value of the field "model3"
Here's a piece of template:
<form action="" method="post" id="simple">{% csrf_token %}
<input type="submit" name="delete" id="simple_delete" value="">
</form>
the value passed from js:
$('.deletebutton').click(function(){
id = $(this).attr('data-id');
$('#simple_delete').attr('value', id);
$('#simple').ajaxForm();
$('#simple_delete').click();
});
Well, respectively plugin jquery.form.js also connected
The problem is this - if submission without ajax all is normal, it works ... and if with Ajax is an error such as incorrect int value ... How to make it work via Ajax?

try this
$('.deletebutton').click(function(){
id = $(this).attr('data-id');
$.ajax(function(){
type:"POST",
url :"/your_url/",
data:{
'id'=id,
}
}).done(function(result){
alert('your json object result render by view :'+result)
})
i think it work,
and i didnt get wat you are doing in i.e $('#simple_delete').click();
can you please describe about that
in view
obj = Model1.objects.get(id = simple_id)
model2.objects.filter(model3__id = id3).delete()
i just split single line query into two lines and if not working
use .select_related()

Related

Flask: request method not picking up the datetime value from web form via AJAX

I am creating a web form where one two fields are of datetime data types. Then I am passing this form data to server via AJAX. Below is the code JQuery snippet.
$(document).ready(function(){
$('#btnSubmit').click(function(){
var start = $("#start").val();
var end = $("#end").val();
$.ajax({
type:'POST',
url: '/interuption',
data: $('#formint').serializeArray(),
success: function(response){
alert(response);
},
error: function(error){
console.log(error);
}
});
});
});
Associated HTML is as follows:
<form id = "formint" class="myForm" method= "post" action="/interuption">
<th>
<label>Start Time Stamp
<input id = "start" type="datetime-local" name="start_timestamp" required>
</label>
</th>
<th>
<label>End Time Stamp
<input id ="end" type="datetime-local" name="end_timestamp" required>
</label>
</th>
</form>
On the server side I am using Flask. I am using request.form.get methods to retrieve the datetime. Then I am trying to push this to MS SQL Server. Below is the Python code snippets.
cnxn = pyodbc.connect(#credentials)
cursor=cnxn.cursor()
query_insert = "INSERT INTO test.dbo.testFeed(start_timestamp,end_timestamp)
VALUES (?,?)"
#app.route('/interuption',methods = ['GET','POST'])
def interuption():
try:
data_1 = datetime.datetime.strptime(request.form.get('start'),%Y-%m-%d %H-%M-%S')
data_2 = datetime.datetime.strptime(request.form.get('end'),%Y-%m-%d %H-%M-%S')
if data_1 and data_2:
cursor.execute(query_insert,(data_1,data_2))
cnxn.commit()
cnxn.close()
return json.dumps({'status':'OK'})
else:
return json.dumps({'error':'data has not been insterted!!'})
except Exception as e:
return json.dumps({'excp':str(e)})
return render_template('form.html')
When I am running the above codes, I am getting an error as follows
{"excp": "time data 'None' does not match format '%Y-%m-%d %H-%M-%S'"}
Clearly that request.form.get is not picking up any value from the web form.
How can I get rid of this?
When sending form data as key-value pairs to the server, the key will be the name attr of the <input> (not id), so you should try request.form.get('start_timestamp') and request.form.get('end_timestamp') instead.

<g:remoteForm> redirect is not happening

I am using a to handle a login. In the case of incorrect credentials, I use Ajax to print an error message on the same web page but in the case of success I would like to forward to another web page. What is happening is that even in the case of success it is printing results on the same page. I know that this has partially to do with the fact that you can't send a redirect to Ajax. However, still a newbie to know how to go about it. Any suggestions?
Here is my gsp section having to do with this form:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" update = "error_message">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
and here is the controller method 'authenticate':
def authenticate = {
try {
MongoClient mongoClient = new MongoClient("localhost", 27017)
DB db = mongoClient.getDB("admin");
def userName = params.username
def passWord = params.password
boolean auth = db.authenticate(userName, passWord.toCharArray())
if (auth)
redirect (action: loggedin)
else {
render "Login or Password incorrect!"
}
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (MongoException e) {
e.printStackTrace();
}
}
def displayerror = {
render "Login or Password incorrect!"
}
def loggedin = {}
As it is, I can't get the gsp corresponding to the 'loggedin' method to display. Any ideas?
Minor adjustments needed to previous poster's most helpful suggestions. This is the code that will actually solve the issue.
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(data)">
<br><br><label>User Name (email): </label><g:textField name = "username" /><br><br>
<label>Password: </label><g:field name = "password" type = "password" /><br><br><br><br>
<div id = "error_message" style = "text-align: center"> </div>
<div style = "text-align: center">(for TWC employees only)</div>
<g:submitButton id = "submit_button" name="Submit"/>
</g:formRemote>
javascript below:
function doResult(data) {
if (data.success == true) {
window.location.href = data.url;
} else {
$("#error_message").html(data.message);
}
}
controller code section below
//success case
render(contentType: 'text/json') {
[success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')]
}
}
else {
render(contentType: 'text/json') {
["success": false, "message": 'Login or Password is incorrect.']
}
importing JSON converter in last set of code isn't needed either.
You are correct that you can't send a redirect using ajax. What you can do, however, is send something back in your ajax response that you can read and redirect if needed.
Instead of just updating the div with the response from your ajax call you will need to send back some JSON data and use the onSuccess attribute of the formRemote tag to pass the results to a function which can act accordingly.
I would suggest you start by reading over the documentation for the formRemote tag, then consider something like the following:
<g:formRemote name="subForm" url="[controller:'admin', action:'authenticate']" onSuccess="doResult(e)">
<br><br><label>User Name (email): </label><g:textField name="username" /><br><br>
<label>Password: </label><g:field name="password" type="password" /><br><br><br><br>
<div id="error_message" style="text-align: center"> </div>
<div style="text-align: center">(for TWC employees only)</div>
<g:submitButton id="submit_button" name="Submit"/>
</g:formRemote>
Notice in the above that onSuccess is now set on the formRemote tag and update is removed. The response from the form submission will now be passed to the javascript function doResult.
This is what the function might look like:
<script>
function doResult(response) {
var result = eval('(' + response.responseText + ')');
if (result.success == true) {
window.location.href = result.url;
} else {
$("#error_message").html(result.message);
}
}
</script>
The only thing left is to change how your controller responds to the form submission. First you will need to add the import for import grails.converters.JSON into your controller. Then change the way it responds. It might look like this:
import import grails.converters.JSON
...
// in the case of an error
render [success: false, message: "Login or Password incorrect!"] as JSON
return
...
// in the case of success
render [success: true, url: createLink(controller: 'whateverController', action: 'whateverAction')] as JSON
return
It may seem like a lot to take in all at once, but once you do it a few times it becomes quite simple. One thing that helps a lot is to read the Grails documentation. It's long, but it's very well written and will help a lot.

Unable to Save form Django

I am trying to save a form to update an existing user, but I am unable to get it to work. The error occurs when I try to save the form. The console shows the error occurs in the view (internal server error).
Form:
class updateFirstName(forms.ModelForm):
class Meta:
model = User
fields = ('first_name',)
def __init__(self, *args, **kwargs):
super(updateInfoForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_id = 'id-updateFirst'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
self.helper.form_action = '/login/userInfoChange/'
self.helper.add_input(Submit('submit', 'Submit'))
view:
#json_view
#csrf_exempt
def userInfoChange(request):
context = RequestContext(request)
if request.method == 'POST':
user = User.objects.get(username=request.user.username)
user_form = updateFirstName(request.POST)
print user_form
if user_form.is_valid():
user_form.save()
print "Valid Form"
return {'success': True}
html:
<form id="updateUsername">
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-success" type="button" id="submit-username">Change</button>
</span>
<input type="text" class="form-control" id="id_firstname" placeholder="First Name: {{user.first_name}}">
<script type="text/javascript">
$('#submit-username').click(function(){
$.ajax({//begin
type: 'POST',
url: '/login/userInfoChange/',
data: $('#updateUsername').serialize(),
success: function(result){
console.log('updateUsername');
}
});
});
</script>
</div><br></form>
Model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
confirmation_code = models.CharField(max_length=128)
reset_code = models.CharField(max_length=128)
address_lineOne = models.CharField(max_length=128)
address_lineTwo = models.CharField(max_length=128)
city = models.CharField(max_length=128)
State = models.CharField(max_length=128)
zipCode = models.CharField(max_length=10)
def __unicode__(self):
return self.user.username
Solution:
first_name = request.POST.get('first_name')
user.first_name = first_name
user.save()
Thanks ejey for resolving my csrf ajax issue.
If you are intending on posting using ajax you ought to use have a view method such as:
def some_ajax_view(request):
data = request.POST.copy()
if request.is_ajax() and request.POST:
...
...
You can get more information on how to process your ajax request without having to compromise on the csrf https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Firstly, you didn't answer my question about the error message. This is a vital step in debugging, and it's very little use coming onto SO and asking questions without first finding the actual error and doing what you can to fix it yourself.
That said, you do have a huge obvious bug in your code. If the request is not a POST, and/or the form is not valid, what are you expecting to happen? Currently, your code just stops; so in either of those cases it will return None, which is an error: all views must return an HttpResponse. If you did look at the error message, that is probably what it would say.
You should ensure that your view at least returns an empty HttpResponse in either of those circumstances. More useful, though, would be a response that actually contains the errors from the form validation.

Django file upload ajax call post using jquery

How exactly do I upload a file using an ajax call ?
My form in template
<form action="images/" enctype="multipart/form-data" method="POST" class="upload">
<table>
{{ form.as_table }}
<td><input type = "button" onclick="" value="Upload" id = "test"/</td>
</table>
</form>
My jQuery function :
$(document).ready(function(){
$("#test").click(function(){
var string = $("form.upload").serialize();
alert(string);
$.ajax({
url :'/test/',
type:'post',
data: {datas:string},
dataType: "json",
success: function(response) {
alert(response);
}
});
});
});
My view :
#csrf_exempt
def test(request):
if request.is_ajax():
form = ImageUploadForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse("Saved !!!!")
Here I have the view for the file upload but the file does not appear in the form variable in the django view . What should I do to get the file in the view ?
The form has a filefield for uploading . It is a model form.
2 important pieces are missing here:
jQuery.serialize() doesn't do anything to file fields. Check out jQuery form plugin for a robust method of posting form with files via Ajax
You need to explicitly pass the uploaded files to the form constructor: form = ImageUploadForm(data=request.POST, files=request.FILES)

Liftweb: create a form that can be submitted both traditionally and with AJAX

Is it possible in Lift web framework to create forms (and links) that react via AJAX, but also work without Javascript support? If so, how?
When I build the form using <lift:form.ajax>, the form's action is set to javascript:// so that it no longer submits without JS. If I build the form without explicit AJAX support, I don't know how to insert the AJAX functionality.
I suppose I could build a RESTful interface (we'll have to build that anyway) and write custom Javascript to submit the form through that. I would like to avoid code duplication, though: if it is possible to handle all three inputs (RESTful, traditional HTTP POST, AJAX) with the same code, that would be best.
Take a look at http://demo.liftweb.net/form_ajax
FormWithAjax.scala
class FormWithAjax extends StatefulSnippet {
private var firstName = ""
private var lastName = ""
private val from = S.referer openOr "/"
def dispatch = {
case _ => render _
}
def render(xhtml: NodeSeq): NodeSeq =
{
def validate() {
(firstName.length, lastName.length) match {
case (f, n) if f < 2 && n < 2 => S.error("First and last names too short")
case (f, _) if f < 2 => S.error("First name too short")
case (_, n) if n < 2 => S.error("Last name too short")
case _ => S.notice("Thanks!"); S.redirectTo(from)
}
}
bind( "form", xhtml,
"first" -> textAjaxTest(firstName, s => firstName = s, s => {S.notice("First name "+s); Noop}),
"last" -> textAjaxTest(lastName, s => lastName = s, s => {S.notice("Last name "+s); Noop}),
"submit" -> submit("Send", validate _)
)
}
form_ajax.html
<lift:surround with="default" at="content">
Enter your first and last name:<br>
<form class="lift:FormWithAjax?form=post">
First Name: <form:first></form:first>
Last Name: <form:last></form:last>
<form:submit></form:submit>
</form>
</lift:surround>
And this will work without javascript:
<form action="/form_ajax" method="post">
<input name="F1069091373793VHXH01" type="hidden" value="true">
First Name: <input value="" type="text" name="F1069091373788OVAAWQ" onblur="liftAjax.lift_ajaxHandler('F1069091373789N2AO0C=' + encodeURIComponent(this.value), null, null, null)">
Last Name: <input value="" type="text" name="F1069091373790VANYVT" onblur="liftAjax.lift_ajaxHandler('F1069091373791CJMQDY=' + encodeURIComponent(this.value), null, null, null)">
<input name="F1069091383792JGBYWE" type="submit" value="Send">
</form>
I dont know a lot about Lift so my answer focuses on alternate way to do it.
This is jQuery based and will do with AJAX when Javascript is usable and traditional POST if there is no Javascript support enabled.
Form:
<form id="ajaxform" action="formhandler.php" method="post" enctype="multipart/form-data" >
<input name="firstname" type="text" />
<input name="email" type="email" />
<input name="accept" type="submit" value="Send" />
</form>
<div id="result"></div>
JS:
note: jQuery $.ajax() sends as application/x-www-form-urlencoded by default, it may be good to set form enctype="application/x-www-form-urlencoded" too.
$("#ajaxform").submit(function(e){
// Alternative way to prevent default action:
e.preventDefault();
$.ajax({
type: 'POST',
url: 'formhandler.php',
// Add method=ajax so in server side we can check if ajax is used instead of traditional post:
data: $("#ajaxform").serialize()+"&method=ajax",
success: function(data){ // formhandler.php returned some data:
// Place returned data <div id="result">here</div>
$("#result").html(data);
}
});
// Prevent default action (reposting form without ajax):
return false;
});
Server side (PHP)
<?php
if (isset($_POST['method']) && $_POST['method'] == 'ajax') {
// AJAX is used this time, only #result div is updating in this case.
} else {
// Traditional POST is used to send data, whole page is reloading. Maybe send <html><head>... etc.
}
?>
What About REST then?
This is something you should decide to use or to not use, it is not something to support as alternate to other methods (ajax, traditional) but more something integrate within other methods.
Of course you can always enable or disable REST feature.
You can always make form method="POST/GET/PUT/DELETE" and ajax call RESTful:
...
$.ajax({
type: 'PUT',
url: 'formhandler.php',
...
...
$.ajax({
type: 'DELETE',
url: 'formhandler.php',
...
But REST asks us to use XML, JSON, ... for requests too
Well, that is not well supported by browsers (without Javascript) but $.ajax() uses application/x-www-form-urlencoded as default encoding.
Ofcourse, with Javascript one can always convert data container to XML or JSON ...
Here's how it can be done with jQuery, JSON object:
/* This is function that converts elements to JSON object,
* $.fn. is used to add new jQuery plugin serializeObject() */
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
But I want one AJAX call that does everything:
You are right, computers should do our work. It's what they are designed for.
So, another thing that needs to be done is to check what http method our original html form wants to use and adapt it to send ajax requests with same method that would be used without javascript support.
This is modified version from under JS: heading used earlier:
...
// Alternative way to prevent default action:
e.preventDefault();
// Find out what is method that form wants to use and clone it:
var restmethod = $('#ajaxform').attr('method');
// Put form data inside JSON object:
var data = $('#orderform').serializeObject();
// Add method=ajax so in server side we can check if ajax is used instead of traditional post:
data.method = 'ajax';
$.ajax({
type: restmethod, // Use method="delete" for ajax if so defined in <form ...>
url: 'formhandler.php',
data: data, // data is already serialized as JSON object
...
Now, our AJAX handler sends data as JSON object using method (post|get|put|delete) that is defined at <form method="put" ...>, if form method changes then our ajax handler will adapt changes too.
That's all, some code tested and is actually in use, some is not tested at all but should work.

Resources