Django iterate through a list of webpages - django

Hi I'm relatively new to python and DJANGO and was wondering if there was a way to load a webpage from a currently loaded webpage after a time delay
For example i have 5 or 6 graphs/charts on separate pages within my django project and want them to be displayed for 5-10 seconds then switch to the next one
I may be just missing something simple here but any help would be appreciated

If you expect them to submit the form within 30 seconds then a meta-refresh is quite a simple way to achieve that.
Otherwise you can use a javascript redirect that fires after a delay. The redirect would check that no action (such as filling out the fields) has been performed during the delay. Something like:
setTimeout(function() {
if (noChange) {
window.location = "http://www.yoururl.com";
}
}, 30 * 1000);

You should use javascript to do that:
$(function(){
setTimeout(checkUserStatus, 30000);
})
function checkUserStatus(){
//Code to check if user hit/click anything
//if yes clear TimeInterval and do the operation
//If no clear Time Interval and redirect to home page
}

Related

How to make a form save to the database every time it is edited in Django?

So I am trying to replicate the Google Docs functionality wherein every time you edit, the document will be saved. Will I be putting an onchange function on every input in the form then sending the data through ajax? How should I approach this or is this even feasible?
Note: I am just asking for some sort of pseudocode or simply the flow-chart of how I should do things.
I think that something like this should works:
jQuery(function($){
function changeFn(){
// make ajax save.
}
var timer;
$("#doc").bind("keyup", function(){
clearTimeout(timer);
timer = setTimeout(changeFn, 2000)
});
});
This will wait 2 seconds(you can try with 3 - 5 seconds) after the user press the last key, then will call the ajax function to save the content. I think that is better than save all the time when the user press a key. Note that if the user press a key before that time, the timeout will be interrupted and will initiate a new count.

Postman - how to loop request until I get a specific response?

I'm testing API with Postman and I have a problem:
My request goes to sort of middleware, so either I receive a full 1000+ line JSON, or I receive PENDING status and empty array of results:
{
"meta": {
"status": "PENDING",
"missing_connectors_count": 0,
"xxx_type": "INTERNATIONAL"
},
"results": []
}
The question is, how to loop this request in Postman until I will get status SUCCESS and results array > 0?
When I'm sending those requests manually one-by-one it's ok, but when I'm running them through Collection Runner, "PENDING" messes up everything.
I found an awesome post about retrying a failed request by Christian Baumann which allowed me to find a suitable approach to the exact same problem of first polling the status of some operation and only when it's complete run the actual tests.
The code I'd end up if I were you is:
const maxNumberOfTries = 3; // your max number of tries
const sleepBetweenTries = 5000; // your interval between attempts
if (!pm.environment.get("tries")) {
pm.environment.set("tries", 1);
}
const jsonData = pm.response.json();
if ((jsonData.meta.status !== "SUCCESS" && jsonData.results.length === 0) && (pm.environment.get("tries") < maxNumberOfTries)) {
const tries = parseInt(pm.environment.get("tries"), 10);
pm.environment.set("tries", tries + 1);
setTimeout(function() {}, sleepBetweenTries);
postman.setNextRequest(request.name);
} else {
pm.environment.unset("tries");
// your actual tests go here...
}
What I liked about this approach is that the call postman.setNextRequest(request.name) doesn't have any hardcoded request names. The downside I see with this approach is that if you run such request as a part of the collection, it will be repeated a number of times, which might bloat your logs with unnecessary noise.
The alternative I was considering is writhing a Pre-request Script which will do polling (by sending a request) and spinning until the status is some kind of completion. The downside of this approach is the need for much more code for the same logic.
When waiting for services to be ready, or when polling for long-running job results, I see 4 basic options:
Use Postman collection runner or newman and set a per-step delay. This delay is inserted between every step in the collection. Two challenges here: it can be fragile unless you set the delay to a value the request duration will never exceed, AND, frequently, only a small number of steps need that delay and you are increasing total test run time, creating excessive build times for a common build server delaying other pending builds.
Use https://postman-echo.com/delay/10 where the last URI element is number of seconds to wait. This is simple and concise and can be inserted as a single step after the long running request. The challenge is if the request duration varies widely, you may get false failures because you didn't wait long enough.
Retry the same step until success with postman.setNextRequest(request.name);. The challenge here is that Postman will execute the request as fast as it can which can DDoS your service, get you black-listed (and cause false failures), and chew up a lot of CPU if run on a common build server - slowing other builds.
Use setTimeout() in a Pre-request Script. The only downside I see in this approach is that if you have several steps needing this logic, you end up with some cut & paste code that you need to keep in sync
Note: there are minor variations on these - like setting them on a collection, a collection folder, a step, etc.
I like option 4 because it provides the right level of granularity for most of my cases. Note that this appears to be the only way to "sleep" in a Postman script. Now standard javascript sleep methods like a Promise with async and await are not supported and using the sandbox's lodash _.delay(function() {}, delay, args[...]) does not keep script execution on the Pre-request script.
In Postman standalone app v6.0.10, set your step Pre-request script to:
console.log('Waiting for job completion in step "' + request.name + '"');
// Construct our request URL from environment variables
var url = request['url'].replace('{{host}}', postman.getEnvironmentVariable('host'));
var retryDelay = 1000;
var retryLimit = 3;
function isProcessingComplete(retryCount) {
pm.sendRequest(url, function (err, response) {
if(err) {
// hmmm. Should I keep trying or fail this run? Just log it for now.
console.log(err);
} else {
// I could also check for response.json().results.length > 0, but that
// would omit SUCCESS with empty results which may be valid
if(response.json().meta.status !== 'SUCCESS') {
if (retryCount < retryLimit) {
console.log('Job is still PENDING. Retrying in ' + retryDelay + 'ms');
setTimeout(function() {
isProcessingComplete(++retryCount);
}, retryDelay);
} else {
console.log('Retry limit reached, giving up.');
postman.setNextRequest(null);
}
}
}
});
}
isProcessingComplete(1);
And you can do your standard tests in the same step.
Note: Standard caveats apply to making retryLimit large.
Try this:
var body = JSON.parse(responseBody);
if (body.meta.status !== "SUCCESS" && body.results.length === 0){
postman.setNextRequest("This_same_request_title");
} else {
postman.setNextRequest("Next_request_title");
/* you can also try postman.setNextRequest(null); */
}
I was searching for an answer to the same question and thought of a possible solution as I was reading your question.
Use postman workflow to rerun your request every time you don't get the response you're looking for. Anyway, that's what I'm gonna try.
postman.setNextRequest("request_name");
https://www.getpostman.com/docs/workflows
I didn't succeed to find the complete guidelines for this issue that's why I decided to invest some time and to describe all steps of the process from A to Z.
I will be observing an example where we will need to pass through transaction ids and in each iteration to change query param for next transaction id from the list.
Step 1. Prepare your request
https://some url/{{queryParam}}
Add {{queryParam}} variable for changing it from pre-request script.
If you need a token for request you should add it here, in Authorization tab.
Save request to collection (Save button in the right corner). For demonstration purpose I will use "Transactions Request" name. We will need to use this name later on.
Step 2. Prepare pre-request script
In postman use tab Pre-request Script to change transactionId variable from query param to actual transaction id.
let ids = pm.collectionVariables.get("TransactionIds");
ids = JSON.parse(ids);
const id = ids.shift();
console.log('id', id)
postman.setEnvironmentVariable("transactionId", id);
pm.collectionVariables.set("TransactionIds", JSON.stringify(ids));
pm.collectionVariables.get - gets array of transaction ids from collection variables. We will set it up in Step 4.
ids.shift() - we use it to remove id that we will use from our ids list (to prevent running twice on the same id)
postman.setEnvironmentVariable("transactionId", id) - change transaction id from query param to actual transaction id
pm.collectionVariables.set("TransactionIds", JSON.stringify(ids)) - we are setting up a new collection of variables that now does not include the id that was handled.
Step 3. Prepare Tests
In postman use tab Tests to create a loop logic. Tests will be executed after the request execution, so we can use it to make next request.
let ids = pm.collectionVariables.get("TransactionIds");
ids = JSON.parse(ids);
if (ids && ids.length > 0){
console.log('length', ids.length);
postman.setNextRequest("Transactions Request");
} else {
postman.setNextRequest(null);
}
postman.setNextRequest("Transactions Request") - calls a new request, in this case it will call the "Transactions Request" request
Step 4. Run Collections
In Postman from the left side bar you should choose Collections (click on it) and then choose a tab Variables.
This is the collection variables. In our example we used TransactionIds as a variable, so put in Current Value the array of transaction ids on which you want to loop.
Now you can click on Run (the button from right corner, near Save button) to run our loop requests.
You will be proposed to choose on which request you want to perform an action. Choose the request that we’ve created "Transactions Request".
It will run our request with pre-request script and with logic that we’ve set in Tests. In the end postman will open a new window with summary of our run.

Meteor - Subscription Does not Update Collection Display Until Refresh (Cache in Template?)

I have a template ("ImageView") displaying collection data, and I use it at two different routes to display different content: at one route it is used to display all data, and at another to display data that belongs to specific user.
Because my layout has various components so I embed the ImageView template within the main template of each route ("Album" and "Profile").
I set up the template level subscription at the two main templates like so:
Template.profile.onCreated ( function() {
Tracker.autorun(function() {
Meteor.subscribe('images', Meteor.userId());
});
});
and
Template.Album.onCreated (function() {
Tracker.autorun(function() {
Meteor.subscribe('images');
}); })
and I have my publication function like so at the server:
Meteor.publish('images', function ( user_id) {
findQuery={}
if (user_id) {
findQuery = {userId: user_id};
}
return Images.find(findQuery);
});
The problem is that, when I navigate between the route between the two pages, the template "ImageView" will not update its content reactively, until I press refresh. (If I enter the url by hand and press enter it will also work fine). Are there cache within the template? But they seemed to be created and destroyed as expected when route changes (checked in onCreated and onDestroyed callbacks).
I have console logged inside the publish function and I made sure the publication is changed when I navigate between the two routes, but the client side is not updating accordingly. I have also tried reactive-publish package, Template.subscriptionReady,FlowRouter.reload() and they don't solve the issue.
Can anyone give me insights on what the issue might be? Btw, I am using FlowRouter.
Any inputs are appreciated. Thank you very much.
You shouldn't use Tracker.autorun in onCreated because you would have to stop the computation manually when the template is destroyed. Use this.autorun instead. It uses the Template autorun.

Django view called twice Firefox

EDIT: This question fixed my issue: What happens when no response is received for a request? I'm seeing retries
I have a weird issue. I have a Django application. The frontend has two forms. I submit the forms together via the same Ajax post method
// code to get and format form data to get into the format I need in the backend
var webURL = "showFormOutput";
$.post(webURL,
dataToSend,
callback
).fail(function(jqXHR, textStatus, errorThrown)
{
console.log("Status: " + textStatus);
console.log("Error: " + errorThrown);
});
In the Django view corresponding to that url, I do the following:
Print a message "View function" to log that I am in the view.
Parse the post data and put it into appropriate variables. Pass these variables to a Python function in a separate file. Let us call this function getQueryResults.
Create two Postgres queries (for two forms) using these variables. Print a log message "Query created".
Use Python's threading module to execute these two queries. I run the following line twice to create two separate threads for the two queries threading.Thread(target=threadFunction, args=(query,).start()
Log in the threadFunction "Query result ready" when the postgres query returns.
This is a long running query - takes up to ten minutes.
In Chrome, this works perfectly. However, in Firefox (and Safari too I think), I get the following issues:
When using Firefox, I can see in pg_stat_activity that two queries are running as expected. However, after about 5 minutes, there are FOUR queries running i.e. two more of the SAME query are started.
This is reflected in my logs also. I get the messages "View Function" and "Query Created" printed AGAIN. This means that somehow, the execution restarted from the view. This happens even on increasing the http.response.timeout to 30000.
Sometimes, Firefox just goes to the fail() case of the $.post and textStatus just says "Error" and errorThrown is blank. Sometimes, it prints my query results as expected but it waits for the second set of queries to finish. I thought it might be an issue with my Python threads but it makes no sense to have the whole view executed again since the threads never call the view anywhere! On the client side, the POST request doesn't seem to be sent again.
Notes: I am using django's filesystem-based cache to cache the query results. Could this be an issue? The second duplicate set of queries turn up even before the first actual set return results so I doubt this is the issue though.
Has anyone got any idea why using Firefox would result in my view being called twice?

How do I call render_template() once per minute flask

I am new to Flask. How do I call render_template('prices.html', stock_price) once every minute for a given page that is fed by constantly changing data?
I tried this:
throttle.Throttle(period=60) # 60 second throttle
while True:
stock_price = get_stock_price()
render_template('prices.html', stock_price=stock_price)
throttle.check() # Check if 60 seconds have passed otherwise sleep
The only thing that does work is return render_template(...). Apparently render_template() must be part of a return-statement. Unfortunately, once return is called the game is over.
How do I accomplish this? I'm assuming it is just ignorance on my part.
When you render the template you run the Flask process and return an HTML after the template file rendered, and as your said, you use return and the game is over.
Even if you will find a really hard-code way to do it, it's not a good way to do it. You will waste too much server calls and a user waiting time.
The easy way to do it
Writing a really simple Python function that return only the stock number(i guess you already have one - get_stock_price() )
But i would decorate it with a route(Lets say "/getprice"). Every one who will get to this page will get a black page but the stock price text.
Now for the real magic - use JQuery-AJAX on the HTML page to call this function:
$.ajax({
type: "POST",
url: "/getprice",
})
.done(function( price ) {
$("#price-box").val(price)
});
Hey but wait, what about my "once per minute"??
of curse we can insert this ajax call into setInerval() function like this:
setInterval(function() {
$.ajax({
type: "POST",
url: "/getprice",
})
.done(function( price ) {
$("#price-box").val(price)
});
}, 1000 * 60);
Tell me if you need any help with that.
The Pro way to do it
Ok, so you managed to send a request for your get_stock_price() function once per minute.
Great.
But what about performance?
I guess your get_stock_price() doing some other request or even some web scraping which, again, could be really hard for the server (think what going on when 10,000 users using this page).
What i would do is:
Store the data from get_stock_price() in your DB every minute(Cron Job would do the job), then when a user asks(AJAX request) for this data, pull it out of the DB.
This way the server will work on the background and the user won't see any different with his data loading speed.