I have a site using GCP python API, which is quite slow at making pull requests. So I have cached the area of the template using this data, and in the view I check if the cache is still active before making any more requests (not a copy n pasted code so if theres any typos ignore em :) )
def gcpProjectsView(request):
gcpprojects = None
cached_time = None
if cache.get(make_template_fragment_key('gcp')) is None:
cached_time=timezone.now()
gcpprojects = get_gcp_projects()
return render (request , 'gcp/gcpprojects.html', {'gcpprojects':gcpprojects,'last_update':cache_time})
To manually update the data, I have a refresh button that points to this view:
def refresh_gcp(request):
cache.delete(make_template_fragment_key('gcp'))
return redirect('gcpProjectsView')
The problem is that if the user clicks the refresh button 5 times the view makes 5 GCP Api calls, it needs to only do 1. How do I resolve this issue?
My suggestion would be to use a simple form with a button. Buttons can be disabled using simple javascript when clicked.
Because you're redirecting back to the same template in the view the button should be re-enabled again once it has 'refreshed'.
In this example snippet replace the action with whatever url routes to refresh_gcp.
<form method="GET" action="<url that points to refresh_gcp>">
<button type="submit" onclick="this.disabled = true;">Refresh</button>
</form>
This was the simplest solution I could think of that didn't involve implementing some sort of token validation for requests.
Use django session :
def refresh_gcp(request):
clicked = request.session.get("click")
if clicked:
return render(request,"your_html",{"disable":True})
# Set Button disable or not in your html by using context...
else:
request.session["click"]="user_click"
cache.delete(make_template_fragment_key('gcp'))
return render(request,"your_html",{"disable":False})
Related
I am creating a flask web application which asks users to complete a quiz through a form and collect data from each session. I use a main.py file, 1 html file with the quiz, and then another one which is supposed to display dynamic results. When the submit button is clicked, it automatically directs users to the second html page with their results. It is my intention to display results based upon what options the user clicks. I attempted to accomplish this by:
Collecting data:
session["symptom1"] = form.symptom1.data
Writing this into a file
user_data.write(form.symptom1.data)
Reading file contents into a variable (3 characters into each variable)
data1 = user_data.read(3)
Assigning a Boolean value to a python variable based upon the data using a conditional:
if data1 == "op3" or data1 == "op4":
global adhd1
adhd1 = True
Rendering this to an html file:
return render_template("takethequiz.html", form = form,adhd1=adhd1,adhd2=adhd2,adhd3=adhd3,adhd4=adhd4)
Creating a conditional in a second html file (treatmentplan.html)=
{% if adhd1 == True %}
Use productivity apps to increase your focus
{% else %}
Great job! You are skilled at staying on task!
{% endif %}
However this does not do anything. Meaning, no matter what I click, the treatment plan is always set to adhd1 = False. How do I combat this?
Code Screenshots on Google Doc: https://docs.google.com/document/d/1uF1Q-zfKNx-d5jzbaIK_BKGbLRm0tCGgaz92-V2hDjE/edit?usp=sharing
Thank you!
I'm generating a map using Folium with Django like so:
views.py:
def viz(request):
dg_map= folium.Map(location=[50.38175,6.2787],
tiles= 'https://tiles.stadiamaps.com/tiles/alidade_smooth/{z}/{x}/{y}{r}.png?api_key=<MY_API_KEY>',
attr= '© Stadia Maps, © OpenMapTiles © OpenStreetMap contributors',
zoom_start=10)
map_details = fetch_data("SELECT id, firstname, lat, long FROM map_details") #helper func to query the DB
for item in map_details:
location = [item[2], item[3]]
popup = f"{item[1]}'s Garden"
marker = folium.Marker(
location = location,
popup = popup,
icon=folium.Icon(color='darkgreen', icon="heart", prefix='fa'))
marker.add_to(dg_map);
m = dg_map._repr_html_()
context = {'map': m}
return render(request, 'accounts/viz.html', context)
This is working as expected.
However, I'd like each marker to redirect towards another page on-click. To make matters worse, I'd need to use the id that's queried in the SELECT statement and include it in the destination link, because the urlpattern of the destination pages is this:
urls.py:
path('garden/<str:id>/', views.garden, name="garden").
What I found out so far:
I found several suggestions on how to add an href to the pop-up (e.g. here) but this is not what I want as it requires the user to click twice.
Some ideas on how to add custom js to Folium's output are mentioned here, but I think it's not implemented yet.
I also found instructions on how this can be done in Leaflet. It seems pretty straight forward, but I'd like to stick with Python/Folium code and keep the logic in my views.py rather than starting js scripting.
Any idea how this can be achieved? Thanks a lot!
I'm building a web app right now that has a couple of text-fields that I would ideally like to be able to copy (individually) using a "copy" button next to each field. Right now I'm attempting to write a Pyperclip function in my main file, and then passing that as an onclick value for a button, but as soon as the page loads, the Pyperclip function executes and my clipboard is updated without pressing anything. So for example:
#app.route('/converted.html', methods = ['GET', 'POST'])
def converted():
pyperclip_Test = pyperclip.copy("apple")
return render_template('converted.html',
pyperclip_Test = pyperclip_Test)
Then in my template file:
Test
<div>Data that I want to copy</div>
I know the pyperclip function isn't copying that div - I retracted the original data that I can pass - but the problem still remains that the script executes without me pressing the button.
Any idea on how to get this working?
you cannot use pyperclip in a webpage ... you are confusing client side and serverside ... you are copying the text on the serverside clipboard, which does nothing for the client(or anyone else)
try something like the following (javascript)
<script>
function clip_text(a_string){
var input = document.createElement('input')
input.id="__copyText__";
input.value = a_string; // OOPS! document.getElementById(divId).innerText;
document.body.appendChild(input);
input.select();
document.execCommand("copy");
var txt = input.value
input.remove()
console.log("OK COPIED: '"+txt+"'")
}
function clip_div(divId){
return clip_text(document.getElementById(divId).innerText)
}
</script>
and then call it like this
Test
<div id="copyme">Data that I want to copy</div>
currently trying to use flask and wtforms to make an html form.
My for template looks like this:
<ul><li>Description:</li>
<li> <textarea class="input" rows="10" cols="50" name="description" onKeyDown="limitText(this.form.description,this.form.countdown,150);"
onKeyUp="limitText(this.form.description,this.form.countdown,150);">
description of the article.You have characters left.
I wanted to use wtforms and just replace:
<textarea..> with {{form.description}}.
But then how do I incorporate the onkeydown event ? I need that to count the number of characters typed already in the textarea.
BTW. My form which I made using wtforms looks like this:
class ItemForm(Form):
title = TextField("Title")
subtitle = TextAreaField("Sub Title")
Description = TextAreaField("Description")
offervalue = FloatField("Offer Value")
imagefile_1 = FileField("Image File 1")
imagefile_2 = FileField("Image File 2")
imagefile_3 = FileField("Image File 3")
QUESTION: HOW SHOULD I STILL INCLUDE THE JAVASCRIPT TO ANY EVEN THAT HAPPENS IN THE TEXTAREA?
thanks for any pointer.
You'll want to use something to select the textarea and bind the keyboard events to it. I'd suggest jQuery like so:
$('textarea .input').keypress(function() {
limitText(this.form.description,this.form.countdown,150);
});
You can see the documentation for the keypress event here: http://api.jquery.com/keypress/ jQuery also can bind to keyup or keydown events.
If you aren't familiar with jQuery, this is a good place to start: http://docs.jquery.com/How_jQuery_Works
It looks like I'm a bit late, but my personal receipe is:
Keep your scripts in separate file, i.e. myscripts.js
Attach myscripts.js to required HTML page via <script
url="<path/to/myscripts.js>"></scripts>
Suppose you have function foo(eventObject) in myscripts.js, and element bar in target HTML-page.
Put into myscripts.js function linker(), that will glue these components (I use jQuery for this as example, but fill free to use plain JavaScript as well):
function linker() {
$(bar).on(event, function blablabla(eventObject) { foo(eventObject); })
}
Call linker() from your HTML page.
In my form i have:
<textarea id="styled" name="content"></textarea>
before submitting the form i cut and paste the following into the text area:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
When I retrieve the value on google app engine:
ImageUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
content_i = self.request.get("content", None)
#content_i is:
u'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=\r\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
This is because of this bug. Though this might solve your problem -> #AndreBrossards Middleware Fix