Flask receiving empty POST form - python

Can't understand, why this code doesn't work, i was trying to understand, but i'm only learning Flask&Py, help me please:
Flask:
#freepylib.route('/register', methods=['POST', 'GET'])
def signup_user():
if request.method == "POST":
username, useremail, userpasswd=request.form['name'], request.form['email'], request.form['password']
reg = Users(uname=username, useremail=useremail, upasswrd=userpasswd)
try:
mydb.session.add(reg)
mydb.session.commit()
token = reg.get_token()
return {'access_token': token}
except Exception as e:
return str(e)
else:
return render_template("register.html")
HTML code:
<form method="POST" name="reg" id="reg">
<input type ="text" class ="fadeIn second" name ="name" placeholder="name">
<input type="text" class="fadeIn second" name="email" placeholder="email">
<input type="text" class="fadeIn third" name="password" placeholder="password">
<input type="submit" name="subm" class="fadeIn fourth" value="Sign Up">
</form>
Error:
(pymysql.err.IntegrityError) (1048, "Column 'uname' cannot be null") [SQL: INSERT INTO `PFL_USERS` (uname, email, upasswrd) VALUES (%(uname)s, %(email)s, %(upasswrd)s)] [parameters: {'uname': None, 'email': None, 'upasswrd': None}] (Background on this error at: http://sqlalche.me/e/13/gkpj)

I think the problem is in your Users class, in the __init__. The kwargs need to match up with how you're calling the constructor from your app code.
For example, changing it to this should help:
def __init__(self, **kwargs):
self.uname = kwargs.get('uname')
self.email = kwargs.get('useremail')
self.upasswrd = kwargs.get('upasswrd')

Special thanks to #ChrisSears, you make my day
Problem was in class, which i forget to add(i'm really sorry)
So, i'll describe:
reg = Users(uname=username, email=useremail, upasswrd=hash_password(userpasswd))
Using this, i've transfer data into Class Users:
def __init__(self, **kwargs):
self.uname = kwargs.get('name')
self.email = kwargs.get('email')
self.upasswrd = kwargs.get('password')
As we can see, name of variables is not correct, so there is the problem, it should be like this:
def __init__(self, **kwargs):
self.uname = kwargs.get('uname')
self.email = kwargs.get('email')
self.upasswrd = kwargs.get('upasswrd')

Related

MultiValueDictKeyError when passing empty file

In my website uploading picture is not compulsory, Therefore when left empty I get
MultiValueDictKeyError
But if i pass an image is dont get an error.
Am I missing some thing?? Thanks in advance....
views.py
if request.method == "POST":
FirstName = request.POST['FirstName']
LastName = request.POST['LastName']
image = request.FILES['image'] #This one
age = request.POST['age']
gender = request.POST['gender']
address = request.POST['address']
PhoneNumber = request.POST['PhoneNumber']
EmailAddress = request.POST['EmailAddress']
Password = request.POST['Password']
RepeatPassword = request.POST['RepeatPassword']
BloodGroup = request.POST['BloodGroup']
try:
if Password == RepeatPassword:
Patient.objects.create(FirstName=FirstName, LastName=LastName, image=image, age=age, gender=gender,
address=address, PhoneNumber=PhoneNumber, EmailAddress=EmailAddress, BloodGroup=BloodGroup)
return redirect('login')
else:
messages.success(
request, ("Passwords do not match. Please try again"))
except Exception as e:
messages.success(
request, ("This email already exists. Try again with another email or recover your account"))
return render(request, 'signup.html')
HTML
<div class="input-div one">
<div class="i">
<ion-icon name="image-sharp"></ion-icon>
</div>
<div class="div">
<h5>Photo</h5>
<input type="file" class="input" name="image">
</div>
</div>
Use .get() instead, i.e:
image = request.FILES.get('image')
It will resolve to None if it can't find it. You can set the default to something else with:
image = request.FILES.get('image', "New default that isn't None")
See: https://www.w3schools.com/python/ref_dictionary_get.asp

Can a GET POST be implemented in a return jsonify(data) function?

I have:
server:
#app.route('/')
def index():
return render_template("index.html")
#app.route('/indexGetData', methods=['GET', 'POST'])
def loadData():
if (request.method == 'POST'):
myval = request.form.get('user_ID')
query = "select * from abc where xyz = :myval"
cursor.execute(query, myval=myval)
# convert the result to json
return jsonify(data)
form:
<form method="post" action ="/indexGetData">
<input type="text" id="userID" name="user_ID">
<input type="submit" value="Search"
</form>
and would like to get values from the user form in the index.html template to pass to the sql query. Please advise... I have been getting Method not allowed error
query = "select * from abc where xyz = " + str(myval)
data = db.engine.execute(query)
ret= []
for i in data:
ret.append(
{
"key": i.key
}
)
return jsonify(ret)

Repeated form data to Django form

Consider a basic Django form:
from django import forms
class TestForm(forms.Form):
first_name = forms.CharField(max_length=50)
last_name = forms.CharField(max_length=50)
When you pass this form request.POST, as in TestForm(request.POST), it receives the QueryDict instance from the requests's form(s):
from django.http.request import QueryDict
qd = QueryDict(mutable=True)
qd["first_name"] = "Brad"
qd["last_name"] = "Solomon"
TestForm(qd).is_valid()
# True
But now what I'd like to do is handle multiple row-like repetitions of these same two fields:
<form method="POST" action="/some/endpoint">
<input type="text" name="first_name">
<input type="text" name="last_name">
<br>
<input type="text" name="first_name">
<input type="text" name="last_name">
<input type="submit" value="OK">
</form>
I.e.
What's the proper way to iterate over each of these cleaned and validated (first_name, last_name) pairs?
If I pass the whole thing to a TestForm, then .cleaned_data only takes the last-seen pair:
>>> qd = QueryDict(mutable=True)
... qd.setlist("first_name", ["Brad", "Joe"])
... qd.setlist("last_name", ["Solomon", "Smith"])
>>> form = TestForm(qd)
>>> form.is_valid()
True
>>> form.cleaned_data
{'first_name': 'Joe', 'last_name': 'Smith'}
(For what it's worth, it does make sense that only the last value is shown because this mimics QueryDict behavior. However, I'd like to access all values rather than just the last-seen.)
If you can't use a formset, you'll just have to do things manually.
The rough idea here is
def view(request):
# (add the usual `if method == POST` stuff here)
first_names = request.POST.getlist('first_name')
last_names = request.POST.getlist('last_name')
thingamabobs = request.POST.getlist('thingamabob')
for first_name, last_name, thingamabob in zip(first_names, last_names, thingamabobs):
f = NameForm(data={
'first_name': first_name,
'last_name': last_name,
'thingamabob': thingamabob,
})
if not f.is_valid:
# ... do something here
f.save() # or something
Getting the data back to the view to re-populate the fields post-POST should things not validate will also be a little annoying here.

Django: edit the choices set of forms.Select widget with dB data linked to current user in templates

Dear Python community,
Could you please share some insights with a newbie like myself regarding the following topic:
I would like to dynamically modify the inputs into form field input, specifically
forms.ChoiceField(choices=((text, name), widget=forms.Select())
As I was not able to access requestfrom class in forms.py, I'd like to try editing the choices from Django template engine. Is it possible to edit the choices, taking the parameters from views.py method using jinja?
The question is conceptual, a few lines of code as an example would be enough, I'll pick it up.
The tricky part is - the data should be dependent on logged-in User's created model instances.
If there's no actual way to do it via python, but js only - please let me know so I don't dry to do the impossible.
Thank you!
Code sample for reference:
forms.py
class InformForm(forms.Form):
flight_number = forms.CharField(5, widget=forms.TextInput())
date = forms.DateField(widget=forms.DateInput(attrs={'class': 'datepicker'}))
template = forms.ChoiceField(choices=tuple([(template.text, template.name) for template in Template.objects.all()]),
widget=forms.Select(attrs={'id': 'select_box',
'onchange': 'javascript:changer();'}))
text = forms.CharField(widget=forms.Textarea(attrs={'id': 'txt_box', 'class': 'latin',
'maxlength': "160", 'onchange': 'javascript:validateTextArea();'}))
template
<form class="form-signin form-container" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form-element-wrapper">
<div class="error-form-element">
<span class="error-span">{{field.errors}}</span>
</div>
<div class="form-label">{{field.label_tag}}</div>
<div class="form-data">{{field}}</div>
</div>
{% endfor %}
<button id="cr_inf" type="submit" class="btn btn-lg btn-primary btn-block stl-color"><span id="loader" class=""></span>Create inform</button>
</form>
views.py
class InformFill(View):
form_class = InformForm
temlate_name = 'distrib_db/inform_fill.html'
def get(self, request):
if request.user.is_authenticated():
form = self.form_class(None)
return render(request, self.temlate_name, context={'form': form})
else:
return redirect('distrib_db:login')
def post(self, request):
if request.user.is_authenticated():
form = self.form_class(user=request.user, data=request.POST)
if form.is_valid():
inform = Inform(flt_numbr=form.cleaned_data['flight_number'], date=form.cleaned_data['date'],
template=form.cleaned_data['text'], request=request)
inform.save()
date = form.cleaned_data['date']
flt_numbr = form.cleaned_data['flight_number']
try:
emails, contacts = get_mail_cnt(date, flt_numbr)
# inform = get_object_or_404(Inform, pk=request['pk'])
paxdata = PaxData(inform=inform, emails=' '.join(emails), contacts=' '.join(contacts))
paxdata.save()
return redirect('/inform/{0}/'.format(inform.pk))
# 'distrib_db:detail', context={'pk': inform.id}
except Exception as e:
return render(request, 'distrib_db/sample.html',
context={'date': date, 'flight_number': flt_numbr, 'error': e})
# return render(request, 'distrib_db/sample.html', context={'date': date, 'flt_numbr': flt_numbr})
return render(request, self.temlate_name, context={'form': form})
else:
return redirect('distrib_db:login')
QuerySet issue:
>>> usr = User.objects.filter(username='aleks')
sample = tuple([(template.text, template.name) for template in usr.template_set.all()])
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'QuerySet' object has no attribute 'template_set'
In InformForm class override __init__
def __init__(self, user, *args, **kwargs):
super(InformForm, self).__init__(*args, **kwargs)
self.fields['template'] = forms.ChoiceField(choices="make choice based on user")

Display blob image in template Google App Engine (Python)

I am trying to display an uploaded blob image. It seems to be storing ok, but won't display on the html template when called. Even seems to be showing up in the logging. When looking at other examples, the only real difference I see is you have to iterate over a list, but really just want to pull only one picture. Any advice you can give is greatly appreciated. -Thanks
Handlers:
class PictureHandler(BaseHandler2):
def get(self, **kwargs):
user_session = self.user
user_session_object = self.auth.store.get_session(self.request)
user_info = models.User.get_by_id(long( self.user_id ))
user_info_object = self.auth.store.user_model.get_by_auth_token(
user_session['user_id'], user_session['token'])
user = self.session.get('user')
uploads = db.GqlQuery("SELECT * FROM UserPictureUpload WHERE user =:1 ORDER BY created DESC", user_info.username).get()
upload_url = blobstore.create_upload_url('/upload')
params = {
'upload_url': upload_url,
'user': user_info.username,
'uploads': uploads
}
return self.render_template('picture.html', **params)
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler, BaseHandler2):
def post(self):
user_session = self.user
user_session_object = self.auth.store.get_session(self.request)
user_info = models.User.get_by_id(long( self.user_id ))
user_info_object = self.auth.store.user_model.get_by_auth_token(
user_session['user_id'], user_session['token'])
user = self.session.get('user')
title = self.request.get('title')
pic = self.request.get("picfile")
if pic:
picture = db.Blob(pic)
upload = UserPictureUpload(title = title, picture=picture, user=user_info.username)
upload.put()
self.redirect('/settings/picture')
class ViewHandler(blobstore_handlers.BlobstoreDownloadHandler, BaseHandler2):
def get(self):
user_session = self.user
user_session_object = self.auth.store.get_session(self.request)
user_info = models.User.get_by_id(long( self.user_id ))
user_info_object = self.auth.store.user_model.get_by_auth_token(
user_session['user_id'], user_session['token'])
user = self.session.get('user')
upload_key_str = self.request.params.get('key')
if upload_key_str:
upload = db.get(upload_key_str)
if upload:
logging.info('** Upload Found** -- %s' % upload.picture)
self.send_blob(upload.picture)
if not upload_key_str:
self.error(404)
return
Routing:
RedirectRoute('/settings/picture', handlers.PictureHandler, name='picture', strict_slash=True),
RedirectRoute('/upload', handlers.UploadHandler, name='upload', strict_slash=True),
RedirectRoute('/view', handlers.ViewHandler, name='view', strict_slash=True)
Html:
<form action="{{ upload_url }}" method="post" enctype="multipart/form-data">
<label for="title">Title:</label>
<input type="text" id="title" name="title" /><br />
<label for="upload">File:</label>
<input type="file" id="upload" name="picfile" /><br />
<input type="submit" value="Upload Picture" />
</form>
<br />
<img src='/view?key={{uploads.key()}}' alt='no image'/></img>
App Engine Log:
INFO 2013-07-30 16:11:20,946 handlers.py:875] ** Upload Found** -- Content-Type: image/jpeg
Content-Length: 775702
Content-MD5: NWE0NGM3YmE1YmJlNGVjODY3MjMzZDY3ZTQ4MDY4NDg=
content-disposition: form-data; name="picfile"; filename="Jellyfish.jpg"
X-AppEngine-Upload-Creation: 2013-07-29 15:41:00.481000
INFO 2013-07-30 11:11:21,005 server.py:584] default: "GET /view?key=ag5kZXZ-c2FuZGVuZ2luZXIeCxIRVXNlclBpY3R1cmVVcGxvYWQYgICAgJjxtgsM HTTP/1.1" 200 -
It looks like you are uploading the blob in blobstore but creating a key from your post upload handler and storing it as another blob on picture property instead of getting the blobkey from the uploaded blobinfo which from here: https://developers.google.com/appengine/docs/python/tools/webapp/blobstorehandlers
you can get with
upload = self.get_uploads()[0]
picture=upload.key()
then that's what you put on your send_blob.

Categories

Resources