Avoid changing the address while send GET request (django) - python

I have url http://127.0.0.1:8000/profile/question/1/ and on the address i have form
i want to have like or dislike button on post. everything work fine but url change is the problem.
it's my code- >
def get_context_data(self, *args, **kwargs):
self.object=self.get_object()
context = super(QuestionDetail, self).get_context_data(**kwargs)
if "like" or "dislike" in self.request.GET:
if "like" in self.request.GET:
if bool(Like.objects.filter(user=self.request.user, question=self.get_object())) == True:
pass
else:
Like.objects.create(user=self.request.user, question=self.get_object())
elif "dislike" in self.request.GET:
if bool(DisLike.objects.create(user=self.request.user, question=self.get_object())) == True:
pass
else:
DisLike.objects.create(user=self.request.user, question=self.get_object())
try:
question = Question.objects.get(id=self.kwargs["pk"])
context['detail'] = question
except ObjectDoesNotExist:
return reverse("Profile:error")
<form class="float-right block">
<button type="submit" name="like" class="block mb-2"></button>
<button type="submit" name="dislike" class="block"></button>
</form>
when i click for example like button, url changed and it's http://127.0.0.1:8000/profile/question/1/?like=
how to avoid this problem? and what is the problem?
thank you

This is correct. When you have multiple submit buttons, on your backend you should have a way to know which submit button was selected. You should have a name and values for each button separately. For example:
<form class="float-right block">
<button type="submit" name="type" value="like" class="block mb-2"></button>
<button type="submit" name="type" value="dislike" class="block"></button>
</form>
The like button will submit the form to:
http://127.0.0.1:8000/profile/question/1/?type=like
And dislike button will submit the form to:
http://127.0.0.1:8000/profile/question/1/?type=dislike
And then in your backend, you can get the type of that to submit button using:
btype = request.GET.get('type', 'like')
# Or if the method of the form is POST use
btype = request.POST.get('type', 'like')

Related

please, I have an AttributeError bug to fix, Please, help me out [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 16 days ago.
Improve this question
I created an address project in my Django project which works fine but I want to the program to avoid users from viewing their billing address and update address page if they have not created an address yet.
This is the views of the code that runs well:
views.py
def register_address(request):
instance = ""
try:
if request.method == "POST":
form = AddressForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
messages.success(request, "You have successfully added a shipping address!")
return redirect('address:billing_address')
except:
pass
return render(request,'address/register_address.html',{'form':form})
def billing_address(request):
address = ""
try:
address = UserAddress.objects.get(user=request.user)
except:
pass
return render(request,'address/billing_address.html',{'form':address})
def update_address(request):
form = UpdateForm()
try:
if request.method == "POST":
form = UpdateForm(request.POST)
if form.is_valid():
address = UserAddress.objects.get(user=request.user)
address.user = request.user
address.country = request.POST.get("country")
address.state = request.POST.get("state")
address.area = request.POST.get("area")
address.city = request.POST.get("city")
address.street_name = request.POST.get("street_name")
address.save()
messages.error(request, "You have successfully updated address.")
return redirect('address:billing_address')
except:
pass
return render(request,'address/update_address.html',{'form':form})
urls.py
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('billing_address/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_address.html
<h2>Register Adress</h2><br>
<form action="" method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:bi lling_address'%}';">View Billing Address</button> <button class="btn btn-secondary" onClick = "window.location= '{% url 'address:update_address' %}';">Update Address</button><br><br>
</div>
billing_address.html
<br><h1><center>Billing Address page!</center></h1><br>
<div class="container">
<h2>Username:</h2> {{form.user|capfirst}}<br>
<h2>Address:</h2> {{form.street_name|capfirst}}, {{form.area|capfirst}}, {{form.city|capfirst}}, {{form.state|capfirst}}, {{form.country|capfirst}}<br><br>
<button class="btn btn-success" onClick = "window.location= '{% url 'address:update_address' %}';">Edit me</button><br><br><br>
But here is an extension of the code I want so that users are unable to view their billing address and update address unless they have created address.
views.py
def register_address(request):
instance = ""
user = ""
try:
form = AddressForm()
if request.method == "POST":
form = AddressForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
user=UserAddress.get(user=request.user)
messages.success(request, "You have successfully added a shipping address!")
return redirect(reverse('address:billing_address',args=[user.pk]))
except:
pass
return render(request,'address/register_address.html',{'form':form,'pk':user.pk})
def billing_address(request,pk):
user = ""
try:
user = UserAddress.objects.get(pk=pk)
if user is not None:
return user
except AttributeError:
messages.error(request, "Please, create an address before viewing address!")
return redirect('address:register_address')
except:
messages.error(request, "Please, create an address before viewing address!")
return redirect('address:register_address')
return render(request,'address/billing_address.html',{'form':user})
urls.py
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('<int:pk>billing_address/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_addres.html
<h2>Register Adress</h2><br>
<form action="" method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:billing_address' pk=pk %}';">View Billing Address</button> <button class="btn btn-secondary" onClick = "window.location= '{% url 'address:update_address' %}';">Update Address</button><br><br>
billing_address.html
<div class="container">
<h2>Username:</h2> {{form.user|capfirst}}<br>
<h2>Address:</h2> {{form.street_name|capfirst}}, {{form.area|capfirst}}, {{form.city|capfirst}}, {{form.state|capfirst}}, {{form.country|capfirst}}<br><br>
<button class="btn btn-success" onClick = "window.location= '{% url 'address:update_address' %}';">Edit me</button><br><br><br>
</div>
There are many minor mistakes such as:
The route should be billing_address/<int:pk>/ not <int:pk>billing_address/.
In register_address view, pk is an empty string in case of GET request, so how can you send an empty string to billing_address view, if it is current logged in user (Assuming already have relationship with inbuilt User model of Django via ForeignKey, AbstractUser or AbstractBaseUser or anything) so you can just send request.user.id to the billing_address view.
Try to use below code.
urls.py:
urlpatterns = [
path('register_address/',views.register_address,name="register_address"),
path('billing_address/<int:pk>/',views.billing_address,name="billing_address"),
path('update_address/',views.update_address,name="update_address"),
]
register_address.html
<form method="POST" onsubmit="myButton.disabled = true; return true;">
{% csrf_token %}
{{form.as_p}}
<input type="submit" class="btn btn-success" name="myButton" value="Submit">
</form><br><br>
<button class="btn btn-primary" onClick = "window.location= '{% url 'address:billing_address' pk=request.user.id %}';">View Billing Address</button>
A view should always return HttpResponse(…) [Django-doc] or one of its subclasses but you are returning string from the view i.e. return reverse('address:billing_address',args=[user.pk]) will return string. So return response object instead of string in your view as
from django.urls import reverse
from django.http import HttpResponseRedirect
return HttpResponseRedirect(reverse('address:billing_address', args=[user.pk]))
Change accordingly in other return reverse also.

Footer contains a form with submit button that leads to "method not allowed"

I have a footer that contains a form on every page. I don't want the user to be redirected to a page when submitting the form. Instead, onclick button leads the user to a change in text in the footer on the same page. However, whenever the user inputs his email, and presses "enter" on the keyboard instead of the button, the page is immediately redirected to a "Method Not Allowed
The method is not allowed for the requested URL."
<form action="" method="POST">
<div id="theDiv" class="col-xl-auto col-md-6 col-12 pt-4 my-sm-0 order-6 ">
<div class="form-group"><label for="email" class="mb-3"><b>Subscribe to our Mailing list</b></label><input type="email" name="email" class="form-control form-control-lg" placeholder="Enter email" id="email"></div><button type="button" class="buttonsqred btn btn-primary btn-lg btn-block my-2 Subscribe mt-4 mb-3" onclick="document.getElementById('theDiv').textContent = 'You Successfully Subscribed!'; document.getElementById('theDiv').style.color = 'red'" >Subscribe</button>
</div>
</form>
#app.route('/subscribers', methods=['POST', 'GET'])
def subscribers():
title = "Subscribers"
if request.method == "POST":
subscriber_email = request.form['email']
new_subscriber = Subscribers(email=subscriber_email)
# Push to DB
try:
db.session.add(new_subscriber)
db.session.commit()
return redirect('/subscribers')
except:
return "There was an error adding your Subscription"
else:
return render_template("subscribers.html")
The action attribute on your HTML <form> tag is empty, that is why it does not work.
The action attribute should be /subscribers or {{ url_for('subscribers') }} if you want to use Jinja.
The type attribute of your <button> is button instead of submit, so clicking the button does not send the form.
Examples:
<form action="/subscribers" method="POST"> ... </form>
<!-- Jinja Example -->
<form action="{{ url_for('subscribers') }}" method="POST"> ... </form>
If you want to send the form without redirection, this question is already answered here (pure JavaScript solution): https://stackoverflow.com/a/54964425/11297557

Button not sending POST request to update object django

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.

Flask: How to have multiple submit requests on one form/route path [duplicate]

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?

How can I access the form submit button value in Django?

I have a Django project that, on one page, has multiple forms (in different tags) that can be submitted to have different effects. In all cases I want the user to be redirected back to the same page, so I use in my view the pattern of submitting the form and then redirecting to the original page. In at least one case, the only difference between two of the forms is the value of the submit button.
In my view I have the code (which is the first time my view function accesses the request.POST):
if request.POST['submit']=='Add':
#code to deal with the "Add" form
and in the template, the first form has a submit button like
<input type="submit" value="Add">
I thought this would work, but when I submit that form, I get an error at the line in view from above:
Key 'submit' not found in <QueryDict: {u'clientyear': [u'2012'], u'csrfmiddlewaretoken': [u'be1f2f051f09f6ab0375fdf76cf6a4d7'], u'ben': [u'123405']}>
Obviously, this does not have a 'submit' key or any key with the value corresponding to the submit button I clicked. So, since this does not work, how can access the value of the submit button or tell which of the forms has been submitted?
Submit is an HTML Form structure... You must use name attribute of form objects as follows... In your template:
<form>
...
<input type="submit" name="list" value="List Objects" />
</form>
<form>
...
<input type="submit" name="do-something-else" value="Do Something Else" />
</form>
In your view:
if 'list' in request.POST:
# do some listing...
elif 'do-something-else' in request.POST:
# do something else
One thing to keep in mind to prevent confusion. The name of the submit button will not show if there is only a single button in the form.
#template.html
<form action="..." method="post">
<input type="submit" name = "first_button" value="Add">
</form>
#view.py
...
'first_button' in request.POST #False
#template.html
<form action="..." method="post">
<input type="submit" name = "first_button" value="Add">
<input type="submit" name = "second_button" value="Remove">
</form>
#view.py
...
'first_button' in request.POST #True if you clicked on that button
I'm little bit late but here is the solution
Problem you are facing
Your are trying to get Button name but getting the initial value of button that is not correct way.
HTML Code
<input type="submit" value="Add">
Python Code/View.py
if request.POST['submit']=='Add':
#code to deal with the "Add" form
Solution
First find button name in request.POST dictionary if exist then get their value.
HTML Code
Add name of your button and their value.
<input type="submit" value="Add" name="add_object">
Views.py
You can find the button name in request.POST dictionary
if request.POST['submit'] == 'add_object':
# Both ways to deal with it
if 'add_object' in request.POST:
Extra Stuff
We have two forms on a page.
First form have 2 buttons with same name subjects but different values fav_HTML and fav_CSS.
Second form also have 2 buttons with same name tutorials but different values
Tutorials_HTML and Tutorials_CSS.
<form action="" method="post">
Form 1
<button name="subject" type="submit" value="interview_HTML">HTML</button>
<button name="subject" type="submit" value="interview_CSS">CSS</button>
</form>
<form action="" method="post">
Form 2
<button name="tutorials" type="submit" value="Tutorials_HTML">HTML</button>
<button name="tutorials" type="submit" value="Tutorials_CSS">CSS</button>
</form>
views.py
We can handle different forms, check which button is clicked then getting their values and do something.
if 'subject' in request.POST: # this section handle subject form (1st Form)
#now we can check which button is clicked
# Form 1 is submitted , button value is subject now getting their value
if 'interview_HTML' == request.POST.get('subject'):
pass
# do something with interview_HTML button is clicked
elif 'interview_CSS' == request.POST.get('subject'):
pass
# do something with interview_CSS button is clicked
elif 'tutorials' in request.POST: #this section handle tutorials form (2nd form)
#now we can check which button is clicked
# Form 1 is submitted , button name is tutorials now getting their value
if 'Tutorials_HTML' == request.POST.get('tutorials'):
pass
# do something with fav_HTML button is clicked
elif 'Tutorials_CSS' == request.POST.get('tutorials'):
pass
# do something with fav_CSS button is clicked

Categories

Resources