I want to delete the selected value from the database in ndb, I have the following html code:
Getting the Data in Rooms as:
Class Method:
all_rooms = Room.query().fetch()
template_values = {
'logout_url': users.create_logout_url(self.request.uri),
'rooms': all_rooms
}
template = JINJA_ENVIRONMENT.get_template('rooms.html')
self.response.write(template.render(template_values))
HTML:
{% for i in rooms %}
<br/>
<form action="/rooms" method="post">
<input type="hidden" name="roomKey" value="{{ i.key }}"/>
<input type="submit" value="Delete" name="button"/>
</form>
{{i.key}}
Room Nummber:{{ i.roomNumber }}
<br/>
{% endfor %}
Which OutPuts As Following:
Key('Room', 4644337115725824) Room Nummber:10
I am passing the key to the delete method which is coming as:
Key('Room', 4644337115725824)
How should I retrieve key from it in order to delete the value Room Value.
Use i.key.urlsafe(). This will convert the key to a "url safe" string which is exactly where you plan to use it: in a url.
When you get the roomKey values back, you can convert them back from strings in urlsafe format to ndb Key objects by doing ndb.Key(urlsafe=roomKey) (see this link).
BONUS TIP: This would be extremely insecure code. Okay if this app is just for you (after sign-in) but dangerous if for untrusted users. Why? Well, someone could mock your HTML with keys for any object of any type and then simulate clicking the delete button. Your GAE-side code would blindly convert the urlsafe strings to keys and delete stuff.
Related
I have a list of tuples in this format: [(a,b,c), (d,e,f),(g,h,i)]. For some reasons, I need to pass it as a hidden field in my form and in my views I need to retrieve it. However, Im not able to do it.
Here is my code snippet:
html template
<form id="form1" action="{% url 'job_recommendations' %}" method="POST">
{% csrf_token %}
<a onclick="document.getElementById('form1').submit();">View more recommendations </a
<input type="hidden" name="recommendations" value="{{ job_recommendations }}"> #it
is the list that I want to pass. It already has correct values
</form>
views.py
def job_recommendations(request):
if request.method == "POST":
recommendations = request.POST['recommendations']
for job, recruiter, percentage in recommendations:
print(percentage)
return render(request, 'recommendations.html')
It's not the best way to do this, but you can use ast module.
Jinja would put [(a,b,c), (d,e,f),(g,h,i)] as string in template. You would get this string in your view, then you can call ast.literal_eval(str) function on this string to convert this string into list.
Please remember that this is very unsecure because it allows user from frontend to execute code on backend.
I have 2 separate forms on a html template called queries.html, one for inputting a company name and one for inputting keywords as seen below.
<form method="POST">
<p>Enter Company Name:</p>
<p><input type="text" name="company_name"></p>
<p><input type="submit" value="submit"></p>
</form>
<p> Name: {{ name }} </p>
<form method="POST">
<p>Enter Keywords:</p>
<p><input type="text" name="keywords"></p>
<p><input type="submit" value="submit"></p>
</form>
<p> Keywords: {{ keywords }}</p>
I want to be able to display the form input in the paragraph tags seen below each form.
Below is the relevant flask code:
#app.route('/queries/', methods=['GET', 'POST'])
def queries():
if request.method == 'POST':
if request.form['company_name']:
name = request.form['company_name']
return render_template('queries.html', name=name)
elif request.form['keywords']:
keywords = request.form['keywords']
return render_template('queries.html', keywords=keywords)
return render_template('queries.html')
My problems are, firstly, the company name when entered does display fine where the {{ name }} element is as it should but when inputting a keyword I get a 'bad request' error. Secondly, I did previously have both inputs working but when I would use one form, it would wipe the displayed data from the other, e.g. when inputting a keyword after having already input and displayed a company name, the keyword would appear at the {{ keyword }} element as it should but the company name would disappear. After some research I may need to use AJAX to keep the all elements displayed but not sure if i'm looking in the right direction. It seems this should be a relatively simple issue to solve, please help! Thanks in advance to any responses.
In Place of :
request.form['company_name']
request.form['keywords']
Use this :
request.form.get("company_name")
request.form.get("keywords")
Flask throws error if there is no value in the form input. Using form.get the flask will try to get the value and will handle if there is no value.
Im using python3 and i have this HTMl which create buttons that it gets from a python list :
</style>
</head>
<body>
<ul>
{% for thing in value %}
<form method="get" action="/loader" value="submit">
<button class="button button">{{ thing }}</button>
</form>
{% endfor %}
</ul>
</body>
</html>
my python code:
#app.route("/test", methods=["GET"])
def test():
a = ["a1","a2"]
return render_template('sbutton.html', value=a)
#app.route("/loader", methods=["GET"])
def loader():
data = request.args.get()
print(data)
return render_template('loader.html', value=password)
So i will see buttons a1 and a2 in the website http://localhost/test
And when i press one of them i will redirect to /loader which is a route in my python code to another html.
I want that when i press a button, for example a1, i will get this information back to my python
inside the loader function.
i tried <form method="get" action="/loader" value="submit">
Added the value="submit but i dont get anything under print(data)
I just need to know on which button client clicked when he is redirected to /loader in my code.
I want to keep this value as a var in my python.
Thanks
data = request.args.get() should be called on the exact parameter you want to fetch, e.g. get('username'). Examples are here. As an aside, the data is passed from HTTP, the protocol that the values are transported through, not HTML, the markup language. If you want all values, request.args will return a dictionary with key-value pairs of all GET parameters passed.
I solved it, i was able to catch the button value name like this :
{% for thing in value %}
<form method="get" action="/loader">
<input type=hidden name="{{ thing }}">
<button class="button button">{{ thing }}</button>
</form>
{% endfor %}
And my code it redirects to :
#app.route("/loader", methods=["GET"])
def loader():
data = dict(request.args)
for key in data:
print(key)
return render_template('loader.html', value=password)
So now after i click the button i get the value back to my python /loader function
If client press on a1 button ill get a1 in python.
A method that is recommended by most of people:
files_form_checked_chkbox = request.POST.getlist("file_of_chkbox")
for every_file in files_form_checked_chkbox:
#do somethig
This is B method that I find:
keys = request.POST.keys()
for key in keys:
if key != "csrfmiddlewaretoken":
#do somethig
This is my template:
<p>List</p>
<form action="..." method="post">
{% csrf_token %}
{% for key in keys %}
<p>
<input type="checkbox" name="file_of_chkbox" value="{{key}}">
<a href="..." >{{key}}</a>
</p>
{% endfor %}
<input type="submit" value="Delete files" />
</form>
Both methods can do same thing.
I see. It's sure that A is better than B and A is explained many time.
I use request
But I want to understand why B is't recommended with reson.
B is not doing the same thing as A.
While looping over request.POST.keys() you are doing a lot of extra work by getting the POST parameters you don't even need.
First option is doing exactly what you need to do - get the list of checkbox values. And it is readable.
I prefer the B method, this one implements the "Synchronizer token pattern" to prevent Cross-site request forgery vulnerability
Learn more about CSRF:
http://en.wikipedia.org/wiki/Cross-site_request_forgery
https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet
I wish to edit ini files over web server, decided to use django, been using it for few days now. I can't figure out how to accomplish this. I have ini file structure looking like this:
{'GROUP', {PROPERTY : VALUE}}
Example when I read this kind of ini file:
[LOG]
FilePath = C:/Log
[CMD]
Level = 5
I will get my data structure filled like this:
{'LOG', {'FilePath' : 'C:/Log',},
{'CMD', {'Level', '5'}}}
Loop looks like this:
for group in settingsDict:
print group # group
for property in settingsDict[group]:
print property , # property
print settingsDict[group][property] # value
I am using ini file parser.
I am having trouble understanding how to correctly develop in django: views.py is some kind of controller for django and templates are views and model would be my ini file (probably linked with db using django model), or am I getting something wrong?
I have no problem passing this dictionary to template, making a for loop in it and creating html tags like: <input type="text" name={{ property }} value={{ value }} maxlength="100" />. But how do I then post all the edited values back to control to save them in file (or db)? I Would need all 3 values, that is GROUP, PROPERTY and VALUE.
Then I discovered django also has html widgets, which you create in views.py and then pass it to template. But this is where I stop understanding things, since I am creating widget in my controller class, but even if I am.
Shall I create a list of all django widgets and pass it to template? Same question occurs, how do I get all the widget values back to controller (views.py)?
Update (11.6.2012):
My code looks like this:
views.py
class DynForm(forms.Form):
def setFields(self, kwds):
keys = kwds.keys()
keys.sort()
for k in keys:
self.fields[k] = kwds[k]
def settings(request):
global Settings #my ini dict
kwargs = {}
for group in Settings:
for property in Settings[group]:
kwargs[property] = forms.CharField(label = property, initial = Settings[group][property])
f = DynForm()
f.setFields(kwargs)
return render_to_response('/settings.html',
{
'textWidget' : f,
})
#csrf_exempt
def save(request):
if request.method == 'POST': # If the form has been submitted...
form = DynForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# process form data
# and return response
settings.html
<form action="/save/" method="post">
{% csrf_token %}
{% for field in textWidget %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label }}: {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Save" /></p>
</form>
The problem is, DynForm(request.POST) returns null so I can't get field values. My request.POST is correct, containing all fields and values. As much as I know, I am not suppose to parse request.POST data "by hands"?
OK, finally figured it out, taking me a lot of time (I am lacking a lot of python and django knowledge). I can't paste final solution because of copy right permissions, here is the concept:
Form
class DynamicForm(forms.Form):
def __init__(self,*k,**kw):
forms.Form.__init__(self,*k,**kw)
# loop over data from **kw
# create field
# set field default value
Notes about this code:
If form doesn't use super(SuperForm, self).__init__(*args, **kwargs), you must use forms.Form.__init__(self,*k,**kw) so you can append fields to form using self.fields attribute.
If you need to use default field value, use self.data[field] = defVal not initial = defVal. Form becomes unbound and you won't be able to parse data in your request.POST method. Unbound form (and with errors) will always return is_valid() False.
With this class, you have no problems parsing request.POST data. Looping over dynamic form fields looks like this:
View
for name,field in form.fields.items():
# name - field name
# form.data[name] - field value
Notes:
For the sake of simplisity use #csrf_exempt tag before POST method. See http://jordanmessina.com/2010/05/24/django-1-2-csrf-verification-failed/
Template code loops over fields in form displaying field label and value separated with :
Template
<form action="/Tris/save/" method="post">
{% csrf_token %}
{% for field in textWidget %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.non_field_errors }}
{{ field.label }}: {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Save" /></p>
</form>
Most of the solution is from here: http://jacobian.org/writing/dynamic-form-generation/ and django documentation.