Moving Between Pages - python

I am trying to move from a web page to another when the user submits a POST.
The problem is that the url doesn't change when I submit the POST and the view function that corresponds to the new page doesn't fire but the template loads and it show only the inputs I hard coded inside it without those I pass in the view function of course.
The Code:
In the urls file:
url(r'^addcross/phase1', views.new_cross_phase_1, name='new_cross_phase_1'),
url(r'^addcross/phase2', views.new_cross_phase_2, name='new_cross_phase_2'),
The view function of the 1st page:
def new_cross_phase_1(request):
if request.method == 'POST':
# my code here
return render_to_response('New/New_Cross_Phase_2.html', {'crosses_names': crosses_names, 'creation_methods' : creation_methods},
context_instance=RequestContext(request))
The view function of the 2nd page:
def new_cross_phase_2(request):
print('Phase 2')
if request.method == "GET":
return render_to_response('New/New_Cross_Phase_2.html', {'cross_form': new_cross_form},
context_instance=RequestContext(request))

You should be redirecting in view 1, not rendering the template from view 2.
return redirect('new_cross_phase_2')

Related

How do I redirect to the same page in Flask, generated by a GET request, following a POST request?

I am creating a webapp with Python/Flask. I am using blueprints.
Say I search for a book and end up at the URL /search?book=somebook&author=someauthor via a GET request. On that page I have buttons for each result which will save that result to the user's saved books. This would be a POST request. However, I want to return the user to the same search page with the same URL params.
So the flow is:
User submits a search and ends up on /search?book=somebook&author=someauthor
User clicks subscribe on one of the results. A POST saves the book to the user's saved books.
User ends up on /search?book=somebook&author=someauthor again and the search result page is repopulated.
I think, incorrectly, I want something like this:
#search_bp.route('/search', methods=["GET", "POST"])
def search():
if request.method == "POST":
# save book to user's saved books
# somehow end up back on the same page from here
elif request.method == "GET":
# use request.args to populate page with results
return render_template("search.html", books=books)
In my mind I want to return redirect(url_for("search_bp.search")) but somehow get the request.args back into the URL. Is my only choice to hardcode the URL, i.e. concatenate a string url = "/search?book=" + request.args.get("book") + "&author=" + request.args.get("author") so that I can return redirect(url)?
You can pass values/variables to flask.url_for, example:
book = request.args.get('book')
author = request.args.get('author')
my_url = url_for('search_bp.search', book=book, author=author)
Additional values/parameters passed to url_for will be added to the URL as GET parameters, then you can do return redirect(my_url).
https://flask.palletsprojects.com/en/1.1.x/api/#flask.url_for

How can I execute defined form validators from HTML before submitting?

I have a defined form created using FlaskForm/WTForms where I also defined the validators of the same form. I would like to know how can I validate it using the validators already defined in my form before submitting it, for example, having one button to validate the form and then another to submit the form.
I'm assuming I need to find a way to execute form.validate() from the html when a button is clicked. My approach was to create a view to only execute form.validate() and call it when a button is clicked using jQuery. However, this is not working. And I'm assuming because the form object created in the "create" view and that is passed to the HTML is not the same as the form object created in the "_validate_form" view. But I don't know what other approaches to take. I would appreciate some ideas on how could I solve this problem.
This is my FlaskForm:
class CreateTripForm(FlaskForm):
truck = SelectField('Truck', widget=CustomSelect(), validators=[selection_required], validate_choice=False)
origin = SelectField('Origin',
widget=CustomSelect(),
validators=[selection_required], validate_choice=False)
material = SelectField('Material',
widget=CustomSelect(),
validators=[selection_required], validate_choice=False)
destination = SelectField('Destination',
widget=CustomSelect(),
validators=[selection_required], validate_choice=False)
sender_comment = TextAreaField('Comment', validators=[validators.Length(max=150, message="Máximo 150 caracteres!")])
submit = SubmitField('Confirm Trip')
This is my view when form.validate_on_submit():
#trips_blueprint.route('/create', methods=['GET', 'POST'])
#login_required
def create():
form = f.CreateTripForm()
if form.validate_on_submit():
trip_dict = {
'truck_id': form.truck.data,
'material_name': form.material.data,
'origin_name': form.origin.data,
'destination_name': form.destination.data,
'sender_username': current_user.username,
'sender_comment': form.sender_comment.data
}
trip = Trip.create(**trip_dict)
return redirect(url_for('trips.create'))
return render_template('create_home.html', form=form)
This is my view to only validate form. Which is not working.
#trips_blueprint.route('/_validate_form', methods=['POST'])
def _validate_form():
print('In _validate_form!')
form = f.CreateTripForm()
if form.validate():
return jsonify(True)
This is the jQuery script I'm using to try to validate the form:
function validateForm(){
$.post( "{{url_for('trips._validate_form') }}" );
}
$('#validation_button').click(function(){
validateForm();
});

why django does not find the url?

I'm new to django, and I'm trying to access the following web page by clicking on "dataset celiac" and acces so to "celiac.html". On the html side, here is my code which corresponds to this part of the page where I click on "dataset celiac":
<div class="visit">dataset celiac</div>
Then, on the views.py side, here is the code corresponding to the view which is supposed to return the html page to celiac.html:
def CeliacView(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = forms.CeliacForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
columns = form.cleaned_data['columns']
algo = form.cleaned_data['algo']
if algo == "Logistic regression" and columns == 'CDR3_IMGT':
return render(request, 'data/cdr3.html', locals())
else:
tableData = get_table_data_to_representation()
context = {'form': forms.CeliacForm(), 'tableData': tableData}
return render(request, 'data/celiac.html', context)
And regarding the urls.py file here is my code:
app_name = 'data'
urlpatterns = [
path('datasets/', views.SetView, name='datasets'),
path('celiac/', views.CeliacView, name='celiac'),
]
Finally, here is what django shows me when I click on celiac dataset: Page not found (404)
Can someone tell me what could be the problem here please? why django does not find the correct url ?
Your href shouldn't be the filename, put the path where your url points you towards. For making it more dynamic, I'd suggest using the url tag. Like so:
<div class="visit">dataset celiac</div>

Multiple Forms on 1 Page Python FLASK

So I am loading all users from a database on a single page and I'm generating a password reset form for each user on the same page rather than having an individual page for each user.
My question is how can I click submit and apply the change for that specific user since I have multiple forms and submit buttons for each user via drop-down menu?
In my case the submit button is the "Reset Password" button.
I'm trying to call the form normally using
if request.method == "POST" and form.validate():
password = request.form['password']
but I'm getting exception error
name 'form' is not defined
I've been trying to solve this for a while but i'm getting pretty confused now as I've got multiple forms (one per user) on the same page.
NOTE : I'm not using WTForms for this task
Thanks
I'm not sure if this one has been answered but here is what i just figured out:
After your standard
if request.method == 'POST':
you can test for the existence of each form item within the request.form data. So add another if statement after the first
if 'my_form_element_name' in request.form:
print ('stuff')
If you have other types of form data such as files, you can do something like:
if request.method == 'POST':
if 'file_element_name' in request.files:
return stuff
elif 'my_form_element_name' in request.form:
return stuff
else: return stuff
else: return stuff
I have four forms in one html file and this method worked for me.

Django temporary view

In my Django Project user is redirect to specific template with content:
"Thanks for your registration"
def success_signup(request):
"""Account created with success."""
return render(request, "account/success.html")
when he register new account with success.
I want to make this template/view temporary.
I.E When the user/somebody go to
"account/success.html"
again should be redirected to the homepage instead of the success.html template.
Unfortunately, I can not find this in the documentation. Thanks in advance!
For the first time pass a get variable first_time=yes. Then check if first_time == "yes", Show this page elif request.user.is_authenticated return back to index page else redirect to login page.
url should look like this
localhost:8000/success-signup/?first_time=yes
views.py
def success_signup(request):
first_time = request.GET.get('first_time')
if first_time == "yes":
"""Account created with success."""
return render(request, "account/success.html")
elif request.user.is_authenticated:
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponseRedirect(reverse('signup'))

Categories