Validating for reCAPTCHA in flask - html

I'm making an error form on my website and it still works fine except for the captcha which is a bit silly. If I fill in all the fields on the text and do not just fill in the captcha, it will still be sent to me and without warning or anything, my validations that I set there will not respond, I need to help with it.
HTML Code:
<form action="{{ url_for('get_contact') }}" method=post>
<div>
<p>
{{ form.csrf_token }}
{{ form.name.label }} <br>
{{ form.name(placeholder='Jméno') }}
<ul>
{% for error in form.name.errors %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
<p>
{{ form.email.label }} <br>
{{ form.email(placeholder='Email') }}
<ul>
{% for error in form.email.error %}
<li style="color:red;">{{ error }}</li>
{% endfor %}
</ul>
</p>
<p>
{{ form.message.label }}<br>
{{ form.message(placeholder='Zpráva') }}
</p>
<p>
{{ form.recaptcha }}
{% for error in form.recaptcha.errors %}
<ul>
<li>{{ error }}</li>
{% endfor %}
</ul>
<input class="contact-submit" type="submit" value="Submit">
Flask Code:
#app.route('/contact', methods=["GET","POST"])
def get_contact():
form = ContactForm()
if request.method == 'POST':
name = request.form["name"]
email = request.form["email"]
message = request.form["message"]
res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
res.to_csv('./contactDatabase.csv', mode='a', header =False)
return redirect(url_for("rgb"))
else:
return render_template('contact.html', form=form)
Flask forms code:
class ContactForm(FlaskForm):
name = TextField("Jméno", [validators.DataRequired(), validators.Length(max=255)])
email = StringField("Email", [validators.DataRequired(), validators.Length(min=6, max=35)])
message = TextAreaField("Zpráva")
recaptcha = RecaptchaField()

You may have forgotten to use form.validate_on_submit()
#app.route('/contact', methods=["GET","POST"])
def get_contact():
form = ContactForm()
if request.method == 'POST' and form.validate_on_submit():
name = form.name
email = form.email
message = form.message
res = pd.DataFrame({'name':name, 'email':email, 'message':message}, index=[0])
res.to_csv('./contactDatabase.csv', mode='a', header =False)
return redirect(url_for("rgb"))
else:
return render_template('contact.html', form=form)
I didn't test the code above so I don't know if it's working.
Check if app.testing is True. 1
The flask-wtforms documentation states that:
For your convenience, when testing your application, if app.testing
is True, the recaptcha field will always be valid.
Also, don't forget you have to set the RECAPTCHA_PUBLIC_KEY and RECAPTCHA_PRIVATE_KEY configuration variables with the respective public and private keys received from your ReCaptcha registration.
1 It returns True if you set it to True directly or setting TESTING to True.

Related

Django custom selection HTML page for django admin form

I have created a custom html template with basic checkboxes to select a value and return the value to the Django admin page.
I have done a 100 times before, but now the value of the selected superprofile does not get captured by the variable "selected_value" in the admin.py
The if statement "if request.method == 'POST':" is getting triggered but i keep getting the value of "selected_value" as none
Driving me crazy, I cannot find anything wrong in the code
The Html template
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_modify %}
{% block extrahead %}
{{ media }}
{% endblock %}
{% block content %}
<form class="change_superprofile_parent_form" method="POST" class="change_superprofile_parent_form">{% csrf_token %}
{% for superprofile in superprofiles %}
<input type="checkbox" name="superprofile_selected" {{ superprofile.checked }} value="{{ superprofile }}"> {{ superprofile }}<br>
{% endfor %}
<input type="submit" value="Submit">
</form>
{% endblock %}
Django admin.py
def change_superprofile_parent(self, request, queryset):
"""
Action to change the superprofile of the selected
"""
queryset = queryset.values_list("id", flat=True)
if request.method == 'POST':
selected_value = request.POST.getlist('superprofile_selected')
eligible_superprofiles = SuperProfile.objects.filter(status='Active')
return render(
request, 'admin/auth/user/change_superprofile_parent.html', context={
'superprofiles': eligible_superprofiles,
}
)

Why the Django update method throwing error even though I am able to update the user profile successfully.?

I have a Django method written to update user profile. The purpose of the method is solved, as I am able to click on the "update" button and modify the existing data.
Note: I have written method to update Default User model and extended User model(custom fields). Below is the code snippet from views
views.py
#login_required(login_url="/login/")
def editUserProfile(request):
if request.method == "POST":
form = UserProfileUpdateForm(request.POST, instance=request.user) # default user profile update
obj = UserProfile.objects.get(user__id=request.user.id)
form1 = UserProfileForm(request.POST or None, instance=obj)
if form.is_valid() and form1.is_valid():
obj.Photo = form1.cleaned_data['Photo']
obj.dob = form1.cleaned_data['dob']
obj.country = form1.cleaned_data['country']
obj.State = form1.cleaned_data['State']
obj.District = form1.cleaned_data['District']
obj.phone = form1.cleaned_data['phone']
form.save()
form1.save()
messages.success(request, f'updated successfully')
return redirect('/profile1')
else:
messages.error(request, f'Please correct the error below.')
else:
form = UserProfileUpdateForm(instance=request.user)
form1 = UserProfileUpdateForm(instance=request.user)
return render(request, "authenticate\\editProfilePage.html", {'form': form, 'form1': form1})
corresponding HTML code.
editProfilePage.html
{% load static %}
{% block content %}
<h2 class="text-center">Edit Profile</h2>
<form method="POST" action="{% url 'editUserProfile' %}">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-warning alert-dismissable" role="alert">
<button class="close" data-dismiss="alert">
<small><sup>x</sup></small>
</button>
<p>Form has error..!!</p>
{% for field in form %}
{% if field.errors %}
{{ field.errors }}
{% endif %}
{% endfor %}
</div>
{% endif %}
{{ form.as_p }}
{{ form1.as_p }}
<!-- {{ form1.dob }}-->
<!-- {{ form1.country }}-->
<!-- {{ form1.State }}-->
<!-- {{ form1.District }}-->
<!-- {{ form1.phone }}-->
<input type="submit" value="update" class="btn btn-secondry">
</form>
<br/><br/>
{% endblock %}
If one see in the first glance I do not see any issue immediately as my purpose of updating the profile is successful.
However, to test, after I update a user profile I logout the user which redirects me to login page, and there I see error "Please correct the error below." three times which is coming from the "else" part of the update method. I also see a message "updated successfully" on the same login screen which is coming from the "if" part of the update method as mentioned above(screenshot attached -- update_error3).
So, I have below observations:
My update method "editUserProfile" is somehow calling the inner most "if - else" together.
I think the issue lies in the HTML page. I could say this because when I click on the "update" button from the profile page, I see "email" field appearing twice on the screen and the "update button to insert the data to database(screenshot attached -- update_error1).
Now, I could see the rest of the fields only after I click on the "update" button further(screenshot attached -- update_error2). Furthermore, this is when I enter all my details and when I click on the "update" button, the data get saved successfully in the database and redirected to the profile page with the new data.
Finally, I think the issue is something related to the HTML code. May be I am wrong.
Any thought?
update_error1
The problem is with your messages rendering on the template.Just add this block of code
to your base template that immediately extends your update template.
{% if messages %}
<ul class="messages ">
{% for message in messages %}
<ol class="breadcrumb ">
<li{% if message.tags %} class="{{ message.tags }} " {% endif %}><strong>{{ message }} {{form.errors}}</strong>
</li>
</ol>
{% endfor %}
</ul>
{% endif %}

storage must be a werkzeug.FileStorage(FLASK-UPLOAD)

Hello Everyone,
This is my first time here. I have been having issues regarding the flask_upload to upload the files. I am not sure where I am going wrong with the flask_upload. Hence every time I have been trying to upload the file it is throwing the error in the title
(** storage must be a werkzeug.FileStorage)
enter image description here**)
I am attaching the pictures of my application factory, along with the config file and the html file.Any help will be greatly appreciated.Since I am not sure where I am going wrong
{% block content %}
<h1>upload files</h1>
<form action="{{ url_for('rep.upload') }}" method="post",enctype="multipart/form-data">
{{ form.hidden_tag() }}
<p>
{{ form.report_title.label }}<br>
{{ form.report_title(size=32) }}<br>
{% for error in form.report_title.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.report_description.label }}<br>
{{ form.report_description(size=64) }}<br>
{% for error in form.report_description.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>
{{ form.report_file.name }}<br>
{{ form.report_file}}<br>
{% for error in form.report_file.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</p>
<p>{{ form.submit() }}</p>
</form>
{% endblock %}
enter code here
(Report Blueprint)
#rep.route("/add",methods=['GET','POST'])
#login_required
#roles_requried("patient")
def upload():
form = AddReportForm()
if form.validate_on_submit():
print(request.files.get('report_file'))
filename = images.save(request.files.get('report_file'),name="Hello",folder="static/img",)
url = images.url(filename)
data = {"report_title":form.report_title.data,"report_description":form.report_description.data,
"report_filename":filename,"report_url":url}
print(data)
new_report = Report(**data)
new_report.save()
flash( 'New report, {}, added!'.format(new_report.report_title), 'success')
return redirect(url_for('user.profile'))
return render_template(template_name_or_list='user/add_report.html',form=form)
enter code here
[config.py]
UPLOADS_DEFAULT_DEST = '/static/img/'
UPLOADS_DEFAULT_URL = 'http://localhost:5000/img/'
UPLOADED_IMAGES_DEST = '/static/img/'
UPLOADED_IMAGES_URL = 'http://localhost:5000/img/'
enter code here
(extensions)
images = UploadSet('images',IMAGES)
enter code here
(Application Factory)
app = Flask(__name__, instance_relative_config=False)
app.config.from_object(config_settings)
handler = RotatingFileHandler(app.config.get('LOGGING_LOCATION'), maxBytes=10240,backupCount=10 )
handler.setLevel(app.config.get('LOGGING_LEVEL'))
formatter = handler.setFormatter(app.config.get('LOGGING_FORMAT'))
handler.setFormatter(formatter)
patch_request_class(app, 32 * 1024 * 1024 )
app.register_blueprint(user)
app.register_blueprint(doc)
app.register_blueprint(adm)
app.register_blueprint(rep)
configure_uploads(app, images)
app.logger.addHandler(handler)
error(app)
extensions(app)

RadioField never validates correctly

I'm new to flask and try to build a simple demographics survey. While validating a StringField (e.g. Nationality) works fine, I have trouble with the RadioField. No error messages occur if I don't provide any input for the RadioField. I think the problem lies in my jinja2 template but I'm not able to find what I'm doing wrong.
Any suggestions?
extract from main.py:
class DemographicsForm(FlaskForm):
Gender = RadioField(
'Gender',
choices=[('M', 'Male'), ('F', 'Female'), ('O', 'Other')],
validators=[InputRequired()]
)
#app.route("/demographics", methods=['GET', 'POST'])
def demographics():
form = DemographicsForm()
return render_template('demographics.html', title='Demographic Information', form=form)
extract from demographics.html:
<div class="form-group">
{{ form.Gender.label(class='radio') }}
{% if form.Gender.errors %}
{{ form.Gender(class='radio is-invalid') }}
<div class="invalid-feedback">
{% for error in form.Gender.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.Gender(class='radio') }}
{% endif %}
</div>
Actually the problem comes from your Jinja code. The way you implemented error handling is pretty confusing. It should be as simple as this one:
<div class="form-group">
{{ form.Gender.label(class='radio') }}
{{ form.Gender(class='radio') }}
{% for error in form.Gender.errors %}
<span style="color: red;">[{{ error }}]</span>
{% endfor %}
</div>
Thus, when you send the form without having selected a radio button, an error message will appear on your page (in the code above it will appear in red) and in your console.
More details here

Simple Form-Handling djangobook, version 2

I am writing a simple search view. My views.py code is
def search(request):
error = False
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True
else:
books = Book.objects.filter(title__icontains=q)
return render(request, 'search_results.html', {'books': books, 'query': q})
return render(request, 'search_form.html', {'error': error})
My search_results.html is
<p>You searched for: <strong>{{ query }}</strong></p>
{% if books %}
<p>Found {{ books|length }} book{{ books|pluralize }}.</p>
<ul>
{% for book in books %}
<li>{{ book.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No books matched your search criteria.</p>
{% endif %}
My search_form.html is
<html>
<head>
<title>Search</title>
</head>
<body>
{% if error %}
<p style="color: red;">Please submit a search term.</p>
{% endif %}
<form action="" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
</body>
</html>
The problem is it is not switching on error = True condition. It is suppose to go to search_form.html in case of error and should reload the search form with error message in red. but it went to search_result.html in both cases.
Any help will be appreciated.
The django doc explains very well how to work with forms. I think you should read : https://docs.djangoproject.com/en/1.6/topics/forms/