Web2py - Uploading an image - python

I have in my controller default.py:
def images():
record = db.images(request.args(0))
form = SQLFORM(db.images, record, deletable=True,
upload=URL('download'), fields=['image'])
if request.vars.image!=None:
# form.vars.image_filename = request.vars.image.filename
form.vars.image_filename = "picture_spark_"+str(auth.user.id)
# form.vars.image_filename = "default"
if form.process().accepted:
response.flash = 'form accepted'
elif form.errors:
response.flash = 'form has errors'
return form
def dashboard():
return dict(img_upload_form=images())
In my view dashboard.html, I use the form like this:
{{=img_upload_form}}
However, the problem is that it doesn't work. I choose an image but after I click Submit, there is no change.
Any help is appreciated!

To solve this problem,
I added a print record line to my default.py controller.
What I observed was that the output was None.
My URL is http://127.0.0.1:8000/Spark/default/home. In essence, home.html does an AJAX call to dashboard.html.
Now, in my controller, I defined it as follows:
def dashboard():
return dict(img_upload_form=images())
What I needed to do was return the same form for home.html
def home():
return dict(img_upload_form=images())
This allowed me to successfully upload images!

Related

Python Flask Form not working anymore, any ideas why?

The app has worked before, but it has been a while. It requests data from the user that gets sent to a machine learning model. The page should be the same with the results posted at the bottom of html page.
app = Flask(__name__, template_folder='templates')
with open(f'model/model.pkl', 'rb') as file:
model = pickle.load(file)
#app.route('/', methods=['GET', 'POST'])
def main():
if request.method == 'GET':
return(render_template('index.html'))
if request.method == 'POST':
input_list = request.form.to_dict()
input_list = list(input_list.values())
input_list = list(map(int, input_list))
result = Predictor(input_list)
if int(result)==1:
prediction='High'
else:
prediction='Low'
return render_template("index.html",prediction_text = 'Thank you for submitting your details. Your credit risk is : {}'.format(prediction))
def Predictor(input_list):
to_predict = np.array(input_list).reshape(1,15)
result = model.predict(to_predict)
return result[0]
I've tried making two templates of the same html form, where one holds the submit button and the other displays the result.

How to GET all the ALL DATA from WTForm?

**How To get All Data in a wtf form with a single command in a dictionary or list without needing to write this much lines of code, specifing every single element in the form and geting data seperately
**
#app.route('/add', methods=['POST', 'GET'])
def add_cafe():
form = CafeForm()
if form.validate_on_submit():
print("True")
cafe_name = form.cafe_name.data
cafe_location = form.cafe_location.data
opening_time = form.opening_time.data
closing_time = form.closing_time.data
coffee_rating = form.coffee_rating.data
wifi_strength_rating = form.wifi_strength_rating.data
power_socket_availability = form.power_socket_availability.data
return render_template('add.html', form=form)
The wtforms documentation says that that's Form.data:
A dict containing the data for each field.
In other words,
#app.route('/add', methods=['POST', 'GET'])
def add_cafe():
form = CafeForm()
if form.validate_on_submit():
data = form.data
print("True", data)
# ...
return render_template('add.html', form=form)

Django Redirect does not work at all within view

I am trying to get my view to redirect to another page after clicking a button that triggers the POST request. I cannot seem to figure out why the redirect doesn't work or why it doesn't even seem to try to redirect.
Here is my view:
def cart1(request):
if request.user.is_authenticated:
#POST
if request.method == "POST":
#JSON Data
data = request.body
new_data = ast.literal_eval(data.decode('utf-8'))
customer = request.user
user_order = Order(user=customer)
user_order.save()
x = 0
while x < len(new_data.keys()):
obj_title = new_data[x]["title"]
obj_price = new_data[x]["price"]
obj_quantity = new_data[x]["quantity"]
obj_extra = new_data[x]["extra"]
total = round(float(obj_price.replace("$", "")))
m = OrderItem(order=user_order, title=obj_title, price=total, quantity=obj_quantity, extra=obj_extra)
m.save()
x += 1
return redirect('checkout-page')
return render(request, 'cart.html')
Any help would be appreciated, thank you
redirect(…) [Django-doc] produces a HttpRedirectResponse, you need to return it, so:
return redirect('checkout-page')
redirect(…) itself thus does not stop the code flow to redirect return a HTTP redirect response, it constructs such response, and your view should then return that response.
you need to be sure the URL name =checkout-page is in the current app otherwise you need to make it redirect('app:checkout-page')
However,I suggest to use from django.http import HttpResponseRedirect

Django Calling a View from a View doesn't change URL

I have two views. One which is called gameReportRoster, and the other gameReportStats.
The basic flow of the views is as follows:
gameReportRoster receives a PK from another view. It then renders some forms and processed some data to get a list of the players who played in the game, as well as players who are being added to the roster.
When the user hits submit, some business logic is completed with some data stored to a temporary Model. At this point, we then need to call the gameReportStats to render the next set of forms. When calling gameReportStats, we need to pass to it one variable called game.
The issue I am facing is that when we call gameReportStats, the URL is not changing. So the Post Request is getting handled in gameReportRoster, although we should now be in gameReportStats.
def gameReportRoster(request, pk):
#login_required(login_url="/login/")
def gameReportRoster(request, pk):
**QUERIES AND FORM RENDERING HERE**
if request.method == 'POST':
if 'submitRoster' in request.POST:
print('submitRoster Was Pressed')
homePlayedList = request.POST.getlist('homePlayed')
awayPlayedList = request.POST.getlist('awayPlayed')
formsetHome = PlayerFormSet(data=request.POST, prefix='home')
formsetAway = PlayerFormSet(request.POST, prefix='away')
**OMMITED FORM PROCESSING DONE HERE FOR READABILITY**
tempGameResult = TempGameResults(game=game)
tempGameResult.save()
tempGameResult.homePlayers.set(homePlayersPlayed)
tempGameResult.awayPlayers.set(awayPlayersPlayed)
return gameReportStats(request, game)
**MORE QUERIES AND FORM RENDERING HERE**
return render(request, "home/game-report-roster.html", context)
def gameReportStats(request, game):
#login_required(login_url="/login/")
def gameReportStats(request, game):
tempGameResult = TempGameResults.objects.get(game=game)
# teams = Team.objects.filter(id__in=teamList)
homeTeam = Team.objects.get(id=game.homeTeam_id)
awayTeam = Team.objects.get(id=game.awayTeam_id)
teamList = [homeTeam.id, awayTeam.id]
teams = Team.objects.filter(id__in=teamList)
homePlayersPlayed = Player.objects.filter(id__in=tempGameResult.homePlayers.values_list('id'))
awayPlayersPlayed = Player.objects.filter(id__in=tempGameResult.awayPlayers.values_list('id'))
gameResultForm = GameResultForm(teams=teams)
formsetGoalHome = GoalFormSet(
queryset=Goal.objects.none(),
form_kwargs={'players': homePlayersPlayed},
prefix='goalHome'
)
formsetGoalAway = GoalFormSet(
queryset=Goal.objects.none(),
form_kwargs={'players': awayPlayersPlayed},
prefix='goalAway'
)
formsetPenaltyHome = PenaltyFormSet(
queryset=Penalty.objects.none(),
form_kwargs={'players': homePlayersPlayed},
prefix='penaltyHome'
)
formsetPenaltyAway = PenaltyFormSet(
queryset=Penalty.objects.none(),
form_kwargs={'players': awayPlayersPlayed},
prefix='penaltyAway'
)
context = {
'formsetGoalHome': formsetGoalHome,
'formsetPenaltyHome': formsetPenaltyHome,
'formsetGoalAway': formsetGoalAway,
'formsetPenaltyAway': formsetPenaltyAway,
'gameResultForm': gameResultForm,
'homeTeam': homeTeam,
'awayTeam': awayTeam,
}
** THIS IF NEVER GETS CALLED **
if request.method == 'POST':
print('Test')
** TEMPLATE GETS PROPERLY RENDERED, BUT URL NEVER CHANGES **
return render(request, "home/game-report-stats.html", context)
urls.py
path('game-report-roster/<str:pk>', views.gameReportRoster, name="gameReportRoster"),
path('game-report-stats/', views.gameReportStats, name="gameReportStats"),
what the actual URL looks like
http://127.0.0.1:8000/game-report-roster/fc4cd6db-d7f9-43b3-aa80-f9d4abfff0e5
Maybe instead of
return gameReportStats(request, game)
try:
return redirect('myappname:your_name_in_urls.py', game)

With Flask-Admin and Flask how can I submit a form\view based on ModelView from code?

With Flask-Admin and Flask how can I submit a form\view based on ModelView from code?
I'm trying to create a separate view\form that would allow user to add multiple entries with one form. Specifically allowing to upload multiple images with common prefix name and common parameters. I'd like to do it by submitting a single-image upload form from code, because it does some additional processing like resizing images and I'd like to let Flask-Admin handle connecting database entries and files.
Here's the form I'd like to submit from code:
class ImageView(ModelView):
def _list_thumbnail(view, context, model, name):
if not model.path:
return ''
return Markup('<img src="%s">' % url_for('media',
filename=form.thumbgen_filename(model.path)))
column_labels = dict(show_in_header="Show In Header?",
path="Image")
form_create_rules = ("name",
"tags",
rules.Text(
"Use this image as header. If more than one image is selected header image will be random each time the page is loaded."),
"show_in_header",
"path")
form_excluded_columns = ("timestamp")
column_formatters = {
'path': _list_thumbnail
}
thumbnail_size = config("media", "thumbnail_size")
form_extra_fields = {
'path': BroImageUploadField('Image',
base_path=IMAGES_FOLDER,
thumbnail_size=(thumbnail_size, thumbnail_size, True),
endpoint="media",
url_relative_path='media',
relative_path=None)
}
def is_accessible(self):
return current_user.is_authenticated
def inaccessible_callback(self, name, **kwargs):
# redirect to login page if user doesn't have access
return redirect(url_for('login', next=request.url))
And here I'm creating a form and I'm just not sure that .process() is the function to submit it? Is there one at all?
lass MultipleImagesUploadView(BaseView):
#expose("/", methods=["GET", "POST"])
def index(self):
if request.method == "POST":
a_form = MultipleImagesForm(request.form)
base_name = a_form.base_name.data
tags = a_form.tags.data
show_in_header = a_form.show_in_header.data
print (request.files.getlist(a_form.images.name))
uploaded_files = request.files.getlist(a_form.images.name)
for i, uf in enumerate(uploaded_files):
try:
name, ext = os.path.splitext(uf.filename)
if ext not in IMAGE_EXTENSIONS:
flash("Image file {} was skipped as it's extension is not supported ({}).".format(uf.filename, ext), category="warning")
continue
image_contents = uf.stream.read()
image_form = ImageView()
image_form.name.data = "{}_{}".format(base_name, i)
image_form.tags.data = tags
image_form.show_in_header.data = show_in_header
image_form.path.data = image_contents
image_form.process()
except Exception as e:
flash ("Unhandled exception: {}".format(e), category="warning")
flash("Images were added to the gallery.", category='success')
a_form = MultipleImagesForm()
print("############", a_form)
return self.render('/admin/multiple_images_upload.html', form=a_form)
I can't figure out a way to submit a form from code, been trying to find the answer in docs and google for hours now with no luck.
Found the issue. In my case I was missing the enctype="multipart/form-data". Without that files part was sent as empty.
Also changed to using from flask_wtf import FlaskForm and enabling it as {{ form.files(class="form-control", multiple="") }} in the template.
Files can then be accessed with uploaded_files = request.files.getlist("files") on POST request, it will hold array of file-objects.
I hope this helps someone. If any additional formatting is required I will add or expand the answer.

Categories