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

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)

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,
}
)

Crispy forms field_class not applying correctly

I have a Django form in which I use crispy-forms along with bootstrap5. Everything was alright until I wanted to changed the Layout of my form. As my form is constructed dynamically, I just wanted to define the value of a set element item which is under the form (field_name, layout_index). The goal was to define it as a FieldWithButton, as I couldn't find another way to do that.
To do that, I modified my helper in the __init__ method of my form :
self.helper[item[1]] = Div(FieldWithButtons(item[0], StrictButton("Add item")), id=f'div_id_{item[0]}', css_class='mb-3 row')
This is rendered nearly correctly in my form, I have the FieldWithButton with Div etc. However, the div which contains my FieldWithButton doesn't take the field_class of my helper that I defined, and instead creates a <divclass='col-10'>...</divclass='col-10'>.
There's juste a space which disappeared and messed everything up. How can I either remove the class='col-10' part of my div and put it as its class or differently define my Field as a FieldWithButton ?
Here's my whole form class if needed :
class ScriptInputForm(forms.Form):
def __init__(self, *args, **kwargs):
variables = kwargs.pop('variables') # All variables to render
variables_names = [*variables] # under the form {'name':['type', 'description']}
super().__init__(*args, **kwargs)
for var in variables_names: # Dynamic creation of the fields
values = variables[var]
field = self.fields[var] = forms.CharField()
field.widget.attrs['placeholder'] = values[1].title()
self.helper = FormHelper(self)
num = 1 # Rough part where I define the tuples ('name', 'index') of all lists in my variables
lists = []
for k,v in variables.items():
if v[0]=='list':
lists.append((k,num))
num+=1
for item in lists: # Part where the problem is coming from
self.helper[item[1]] = Div(FieldWithButtons(item[0], StrictButton("Add item")))
self.helper.add_input(Submit('submit', 'Submit'),)
self.helper.label_class = 'col-2'
self.helper.field_class = 'col-10'
self.helper.form_action = reverse_lazy('scripts:data_input')
And the rendered HTML :
<div>
<div class="mb-3 row">
<label for="id_liste" class="col-form-label col-2">Liste</label>
<divclass="col-10"> <!-- With <div class="col-10"> everything's ok -->
<div class="input-group">
<input type="text" name="liste" placeholder="Your List" class="textinput textInput form-control" id="id_liste">
<button class="btn" type="button">Add item</button>
</div>
</divclass="col-10">
</div>
</div>
Seems like it was an error in crispy-bootstrap5.
The FieldWithButtons display is defined in field_with_buttons.html whose code is the following :
<div{% if div.css_id %} id="{{ div.css_id }}"{% endif %} class="mb-3{% if 'form-horizontal' in form_class %} row{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}{% if div.css_class %} {{ div.css_class }}{% endif %}" {{ div.flat_attrs }}>
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="{% if 'form-horizontal' in form_class %}col-form-label {% else %}form-label {% endif %}{{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</label>
{% endif %}
<div{% if field_class %}class="{{ field_class }}"{% endif %}> <!-- Here -->
<div class="input-group{% if input_size %} {{ input_size }}{% endif %}">
{% if field.errors %}
{% crispy_field field 'class' 'form-control is-invalid' %}
{% else %}
{% crispy_field field 'class' 'form-control' %}
{% endif %}
{{ buttons|safe }}
</div>
{% for error in field.errors %}
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="text-danger mb-0"><small><strong>{{ error }}</strong></small></p>
{% endfor %}
{% include 'bootstrap5/layout/help_text.html' %}
</div>
</div>
Just had to add a space at the start of the second div to fix the issue.

Validating for reCAPTCHA in flask

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.

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

jinja2 returning wrong values from sqlite database

I have some code, in Python and sqlite, which when executed and printed, returns the correct data. But when I try pass it to HTML, it is retrieving data from the wrong table and displaying it to the HTML.
For example, I execute the following python code:
comments = c.execute('''SELECT * FROM comments''')
conn.commit
for each in comments:
print(each)
newsubs = c.execute('''SELECT * FROM submissions WHERE Signiture = signiture AND Client_ID = client_ID ORDER BY date DESC''')
conn.commit()
print("hello")
var = "hello,!"
return render_template('profile.html', comments = comments, newsubs = newsubs)
Then, I have the following HTML code calling in comments and newsubs to display the data:
{% for y in newsubs %}
<br>
<div id="subcss">
<legend><strong> {{ y[2] }} </strong> {{ y[4] }} <br><br></legend>
{{ y[3] }} <br><br>
<p id = "sig"><strong>Signiture:</strong> {{ y[5] }}</p>
{{ y[1] }} <br><br>
<div id="subcss">
<form action="/comments" method="post">
<textarea name="comment" rows="7" cols="76">Write a comment...</textarea><br>
<input type="submit" value="Submit"><br><br><br>
<button onclick="myFunction()">View Comments</button>
<div id="comdiv">
{% for z in comments %}
<strong>Date:</strong> {{ z[0] }} <br>
<strong>Comment:</strong> {{ z[1] }} <br><br>
{{ z[2] }}
<br>{ z[3] }} {{ z[4] }}
<br>
{% endfor %}
</form><br>
</div>
{% endfor %}
</div>
</div>
The problem is is that the output to the webpage from this code:
{% for z in comments %}
<strong>Date:</strong> {{ z[0] }} <br>
<strong>Comment:</strong> {{ z[1] }} <br><br>
{{ z[2] }}
<br>{ z[3] }} {{ z[4] }}
<br>
{% endfor %}
Is displaying data from the submissions table, not the comments table.
Any help or anything is greatly appreciated.