I have a scheduling app with Event objects and I'm trying to create a form that will allow the user to update an Event that already exists by the press of the button. However, when the user presses the button it doesn't seem to do anything. It just refreshes the page.
{% for a in availability %}
<form method='POST'>
<li><a class="btn btn-primary" href="{% url 'updateevent' a.id %}" type="submit" role="button">{{a.day}}: {{a.start_time}} - {{a.end_time}}</a></li>
</form>
{% endfor %}
view.py:
def updateevent(request, pk):
if request.method == 'POST':
try:
form = EventForm(data=request.POST, instance=post)
updatedEvent = form.save(commit=False)
updatedEvent.requester_user = request.user
updatedEvent.notes = None
updatedEvent.save()
return redirect('/')
except ValueError:
print(form.errors)
return render(request, 'events/createevent.html', {'form':EventForm(), 'error':'There was an error. Please make sure you entered everything correctly!'})
else:
return redirect('/')
I want the user that presses the button to become the "requester_user", a blank field in my Event object. How can I make this happen?
Anchor tag triggers GET request. You should use <button type="submit"></button> or <input type="submit"> for POST request.
Related
when someone subscribes to the newsletter i automatically want to remove the popup for the user that just subscribed, i tried create a subscribed = False then change it to subscribed = True when a user subscribes. but it doesnt work. i can easily achieve this is a user is logged i, but in this case even unauthenticated users can also subscribe to the newsletter so that is where the issue comes in.
views.py
subscribed = False
if request.method == "POST":
form = NewsLetterForm(request.POST)
if form.is_valid:
form.save()
messages.success(request, f"Subscription Successfull, Thank you!! - Now check your mail")
subscribed = True
return redirect('/')
else:
form = NewsLetterForm()
templates.html
{% if subscribed != True %}
<p class="mb-0">Subscribe to our <b>NewsLetter</b></p>
<form class="form-inline" method="POST">
{% csrf_token %}
{{form.email}}
<button type="submit" class="btn btn-success-soft btn-sm" type="submit">Get Now</button>
{% endif %}
Django Close Bootstrap Modal On Submit
this solved my question for me, i had to do was close it when a user submits the form
I have a very basic Django view:
def myview(request):
if request.method == 'POST':
if 'button1' in request.POST:
form1 = form = myForm(request.POST)
# check whether it's valid:
if form.is_valid():
profile = form.save()
profile.user = request.user
profile.save()
messages.success(request, f"Success")
return HttpResponseRedirect(request.path_info)
else:
form = myForm()
return render(request,
"main/mytemplate.html",
context={"form":form})
And its template:
<form method="post" novalidate>
{% csrf_token %}
{% include 'main/includes/bs4_form.html' with form=form %}
<button name="button1" type="submit" class="btn btn-primary">SUBMIT</button>
</form>
Everything works here, when this form is used, some data is saved on my DB. What i would like to change, though, is the page reload after the form is used.
When the Submit button is hit, the page will be refreshed. Since it makes the navigation way slower, i would like to have the view not refreshing the page each time the form is used.
Is it possible to accomplish this in Django? For example, instead of refreshing the page, i would like to only load part of it, or to have a 'Reload' icon while the view is doing its work.
I'm pretty new to Ajax, so i don't know how to get started on this.
My problem is: when an user refresh a form, the data in the Form is sent.
I have a Form with a POST request.
The user writes his name, mail and a message. If the mail is correct, the message is sent.
In my view, if the Form is valid, I add the message in my model Message.
After that I disable the "Send" button. But if the user refreshes the page, my view is called, and another row is added in my model.
I would like, when the user refreshes the page, to block the POST.
My View:
def contact(request):
form = MessageForm(request.POST or None)
if form.is_valid():
name = form.cleaned_data['name']
message = form.cleaned_data['message']
mail = form.cleaned_data['mail']
new_message = Message()
new_message.name = name
new_message.message = message
new_message.mail = mail
new_message.save()
envoi = True
return render(request, 'vautmieux/contact.html', locals())
My URL:
path('contact/', views.contact, name='contact'),
My HTML:
<form action="{% url "contact" %}" method="post">
{% csrf_token %}
<div class="row">
<div class="col-md-6">
{{ form.name }}
{{ form.mail }}
</div>
<div class="col-md-6" >
{{ form.message }}
</div>
<button id="sendMessageButton" type="submit">ENVOYER LE MESSAGE !</button>
</div>
{% if envoi %}Votre message a bien été envoyé !{% endif %}
</form>
This is the main reason why people implement the Post/Redirect/Get pattern [wiki]. In case of a successful POST request, you should return a redirect to a URL. As a result the browser will perform a GET, and in case the browser thus performs a refresh later, it will make a GET again.
def contact(request):
if request.method == 'POST':
form = MessageForm(request.POST)
if form.is_valid():
form.save()
return redirect('some-message-successful-view')
else:
form = MessageForm()
return render(request, 'vautmieux/contact.html', {'form': form})
Here 'some-message-successful-view' needs to be replaced with the name of a view you trigger when sending a message was succesful. This can be the same view as the one defined here. I advice to use Django's message framework [Django-doc] to send a message to the user that the message has been submitted successfully.
This question already has answers here:
Determine which WTForms button was pressed in a Flask view
(1 answer)
Validate WTForm form based on clicked button
(1 answer)
Closed 5 years ago.
I'm making a blog in flask and I want to make it where I could submit the post as a draft or as a public post. I gave it two buttons with the names "create_draft" and "create_post".
Each submit request is supposed to send the data to a different database table.
The problem is I could only submit the form when I hit the Create Draft button but I get a 400 error saying "Bad Request" when I hit the Submit Post button
<form action="{{ url_for('create') }}" method="post" class="well">
<h2 class="form-signin-heading">Create Blog Post</h2>
{{ form.hidden_tag() }}
{{ wtf.form_field(form.title) }}
{{ wtf.form_field(form.url) }}
{{ wtf.form_field(form.category) }}
{{ wtf.form_field(form.body) }}
<input class="btn btn-lg btn-primary" type="submit" name="create_draft" value="Create Draft">
<input class="btn btn-lg btn-primary" type="submit" name="create_post" value="Create Post">
</form>
What the conditional in the view is trying to say is if I click the button with the name 'create_draft' it submits the form data to the Draft table in the database and if I click the button with the name 'create_post' then it submits to the Post table.
#create posts
#app.route('/dashboard/create', methods=['POST', 'GET'])
#login_required
def create():
admin = True
form = PostForm()
the_id = current_user.get_id()
the_name = current_user.name
if form.validate_on_submit():
if request.form['create_draft'] and request.method == "POST":
draft = Draft(request.form['title'], request.form['url'], request.form['body'], request.form['category'], the_name)
db.session.add(draft)
db.session.commit()
return redirect(url_for('dashboard'))
elif request.form['create_post'] and request.method == "POST":
post = Post(request.form['title'], request.form['url'], request.form['body'], request.form['category'], the_name, the_id)
db.session.add(post)
db.session.commit()
return redirect(url_for('dashboard'))
return render_template('posts/create.html', form=form, admin=admin)
Also when I switch the order of the conditionals it only submits the from first conditional listed but I get a 400 "Bad Request" error when I try to submit the request in the 'elif' statement.
Does anyone know how to make it possible to submit on a route with multiple request options without getting a 400 error?
I'm coding a login. When I programmed the form by hand I got it working.
The code below works:
views.py
def login_view(request):
if request.method == 'GET':
return render(request, 'app/login.htm')
if request.method == 'POST':
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is None:
return HttpResponseRedirect(reverse('error'))
if not user.is_active:
return HttpResponseRedirect(reverse('error'))
# Correct password, and the user is marked "active"
auth.login(request, user)
# Redirect to a success page.
return HttpResponseRedirect(reverse('home'))
template:
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<p><label for="id_username">Username:</label> <input id="id_username" type="text" name="username" maxlength="30" /></p>
<p><label for="id_password">Password:</label> <input type="password" name="password" id="id_password" /></p>
<input type="submit" value="Log in" />
<input type="hidden" name="next" value="" />
</form>
Great! But now I want to do the same thing using Django's forms.
The code below is not working because I get is_valid() == False, always.
views.py:
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request.POST)
print form.is_valid(), form.errors, type(form.errors)
if form.is_valid():
## some code....
return HttpResponseRedirect(reverse('home'))
else:
return HttpResponseRedirect(reverse('error'))
else:
form = AuthenticationForm()
return render(request, 'app/login.htm', {'form':form})
template:
<form action="{% url 'login' %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
There are a bunch of people on stackoverflow complaining that they get is_valid always false. I have read all those posts, and as far as I can tell I'm not making any of those mistakes. I found a new mistake to make :-)
EDIT: I added a print in the code. The output when opening the login view and submitting is
[27/Dec/2013 14:01:35] "GET /app/login/ HTTP/1.1" 200 910
False <class 'django.forms.util.ErrorDict'>
[27/Dec/2013 14:01:38] "POST /app/login/ HTTP/1.1" 200 910
and so is_valid() is False, but form.errors is empty.
It turns out that Maxime was right after all (sorry) - you do need the data parameter:
form = AuthenticationForm(data=request.POST)
The reason for that, though, is that AuthenticationForm overwrites the signature of __init__ to expect the request as the first positional parameter. If you explicitly supply data as a kwarg, it will work.
(You should still leave out the else clause that redirects away on error, though: it's best practice to let the form re-render itself with errors in that case.)
Check out form.errors which will help you find out why.
If situation arises, that you don't have an option (I was trying to work with bootstrap modals and it was just not working), I had to do this, or else the modal would always trigger even if the form had not issues (and the is_valid is always False by default)
What I needed:
Show modal when I click a button
if errors, show on the same page, the modal, with the error.
In the modal template:
{% if not brand_form.is_valid and brand_form.errors %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(window).on('load', (function() {
$('#brandAddModal').modal('show');
}));
</script>
{{ brand_form.non_field_errors }}
{% endif %}
In the view:
def add_brand_form(request):
form = BrandForm()
if request.method == 'POST':
form = BrandForm(data=request.POST)
if form.is_valid():
return HttpResponseRedirect('/home')
else:
return render(request, template_name='home.html', context={'brand_form':form})
return render(request, template_name='modal_add_brand.html', context={'brand_form':form})