URL is adding automatically - Django - python

I have got a problem while redirecting to the edit form.
SO what I am doing is that whenever user clicks on edit button it redirects to "editadmin/{{admin.id}}" using form action = "editadmin/{{admin.id}}" in HTML.
URL path is
path("editadmin/<int:id>", views.editadmin, name="editadmin")
path("update/<int:id>", views.updateadmin, name="updateadmin")
Views.py
#csrf_exempt
def editadmin(request, id):
admin = Admin.objects.get(id=id)
return render(request, "editadmin.html", {"admin": admin})
#csrf_exempt
def updateadmin(request, id):
if request.method == "POST":
admin_id = request.POST["admin_id"]
admin_id = str(admin_id).strip().upper()
name = request.POST["name"]
name = str(name).strip()
if db_name equals to name:
messages.error(request, "Admin name already exists")
return redirect("editadmin/" + str(id))
editadmin.html
<form method="post" class="post-form" action="/update/{{admin.id}}">
<input type="hidden" name="id" id="id" required maxlength="20" value="{{ admin.id }}"/>
{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label"><h4 style="margin-left:40px">Admin ID : </h4></label>
<div class="col-sm-4">
<input type="text" name="admin_id" required style="margin-left:20px; height:38px; width:300px;
border-radius: 5px" id="admin_id" value="{{ admin.admin_id }}"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label"><h4 style="margin-left:40px">Name : </h4></label>
<div class="col-sm-4">
<input type="text" name="name" style="margin-left:20px; height:38px;
border-radius: 5px; width:300px" required id="name" value="{{ admin.name }}"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-1 col-form-label"></label>
<div class="col-sm-4">
<button type="submit" class="btn btn-success" style="margin-left:210px">Submit</button>
</div>
</div>
So what I want is that Whenever user submits invalid name in editadmin.html (URL - editadmin/1 ), it should redirect to the same URL editadmin/1 but what it does is it appends update/ which redirects to update/editadmin/1
How to fix this? I dont want update/ to get appended after redirecting to same form.

update/ is appending because you mentioned your form action to this URL. So instead of mentioning action in your form, you can do something like this.
#csrf_exempt
def updateadmin(request, id):
if request.method == "POST":
admin_id = request.POST["admin_id"]
admin_id = str(admin_id).strip().upper()
name = request.POST["name"]
name = str(name).strip()
# asuming you are checking if admin with this name already exists in database
if db_name equals to name:
messages.error(request, "Admin name already exists")
return redirect("editadmin/" + str(id))
# It mean user enter a unique name
else:
# your logic to save the incoming user here.
message.success(request, "Your success message")
return redirect(f'/update/{admin_id}')
and make sure to update your form from this:
<form method="post" class="post-form" action="/update/{{admin.id}}">
to this:
<form method="post" class="post-form" action="">

Related

How to fix "Method not allowed" error in Python Flask app

I have a defined route in my Python Flask app(which worked fine).
#app.route('/insertpage', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
companyname = request.form['companyname']
username = request.form['username']
userpass = request.form['password']
new_company= Grocery(companyname=companyname,
username=username, userpass=userpass)
try:
db.session.add(new_company)
db.session.commit()
return render_template('index.html', data=Todos.query.all())
except:
return "The problem occurred while adding a new company...."
else:
groceries = Grocery.query.order_by(Grocery.created_at).all()
return render_template('index.html', groceries=groceries)
And I am collecting information in my HTML page:
<form action="/" method="POST">
<div class="form-row">
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New company:</label>
<input type="text" class="form-control" name="companyname" id="newStuff" placeholder="Enter name of new company">
</div>
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New username:</label>
<input type="text" class="form-control" name="username" id="newStuff" placeholder="Enter username...">
</div>
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New password:</label>
<input type="text" class="form-control" name="password" id="newStuff" placeholder="Enter password...">
</div>
<div class="col-sm-3 my-1">
<button type="submit" class="btn btn-primary btn-block">Add</button>
</div>
</div>
</form>
After a couple of successful CRUD operations, I am facing the following error(even if I defined 'POST' and 'GET' in my def).
Method Not Allowed
The method is not allowed for the requested URL.
The action attribute of your HTML form needs to match the name of your Flask route.
Your page is sending a POST to url '/' , so it isn't hitting your route, which is for the path '/insertpage'
You should change it to <form action="/insertpage" method="POST">

Image is not coming up properly

I'm working on a little e-commerce site. when I post a product from my site, the image(picture) doesn't show but when I post from the admin panel, the image shows so I don't why. I need help on this please. This is the code.
The code below is from the model.py
class OrderedItem(models.Model):
name = models.CharField(max_length=50)
price = models.FloatField()
image = models.ImageField(upload_to='pics')
def __str__(self):
return self.name
The code below is from the views.py
def additem(request):
if request.method == 'POST':
stock_name = request.POST['stock_name']
stock_price = request.POST['stock_price']
stock_image = request.POST['stock_image']
new_item = Stock(stock_name=stock_name, stock_price=stock_price, stock_image=stock_image)
new_item.save()
return redirect('/')
else:
return render(request, 'post.html')
the code below is from the html page
<form action="{% url 'additem' %}" method="post">
{% csrf_token %}
<div class="form-group">
<input type="text" name="stock_name" id="" placeholder="stock_name">
</div>
<div class="form-group">
<input type="text" name="stock_price" id="" placeholder="stock_price">
</div>
<div class="form-group">
<input type="file" name="stock_image">
</div>
<div class="form-group">
<input type="submit" value="Additem" class="btn btn-primary btn-lg">
</div>
</form>
You need to add enctype='multipart/form-data' in the form otherwise no file will be accepted.
<form method="POST" action="" enctype='multipart/form-data'>
To get the images inputted in your html file
stock_image = request.FILES['stock_image']

Django doesn't read form

I have form:
<form id="contact-form" class="contact__form" method="POST" action="{% url 'backcall' %}">
{% csrf_token %}
<span class="text-color">Send letter</span>
<div class="form-group">
<input name="name" type="text" class="form-control" placeholder="Name">
</div>
<div class="form-group">
<input type="tel" name="phone" class="form-control" placeholder="Phone (+380)" pattern="[\+][3][8][0]\d{9}" minlength="13" maxlength="13" />
</div>
<div class="form-group">
<input name="email" type="email" class="form-control" placeholder="Email">
</div>
<div class="form-group-2 mb-4">
<textarea name="message" class="form-control" rows="4" placeholder="Your letter"></textarea>
</div>
<button class="btn btn-main" name="submit" type="submit">Send</button>
</form>
views.py:
def backcall(request):
backcall = BackCall(name = request.POST['name'], phone = request.POST['phone'], email=request.POST['email'] , message = request.POST['message'])
backcall.save()
return redirect('thanks')
models.py
class BackCall(models.Model):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=13)
email = models.EmailField()
message = models.TextField(default=None)
datetime = models.DateTimeField(auto_now_add=True)
When I fill out the form and submit nothing happens. When I follow the link 'backcall/' I get an error.
What the problem can be connected with and how to fix it?
Please, search more, exist the solution
Use the MultiValueDict's get method. This is also present on
standard dicts and is a way to fetch a value while providing a default
if it does not exist.
def backcall(request):
backcall = BackCall(name = request.POST.get('name'), phone = request.POST.get('phone'), email=request.POST.get('email') , message = request.POST.get('message'))
backcall.save()
return redirect('thanks')
You should check whether or not the record exists in your database, I think, a quick example would be:
def backcall(request):
obj, created = BackCall.objects.get_or_create(email=request.POST.get('email'),
defaults={'phone': request.POST.get('phone'),
'name': request.POST.get('name'),
'message': request.POST.get('message')}
if created:
return redirect('thanks')
return ...

How to pass context from view to action in html file in django?

I am passing context from view.py file
def change_password(request,pk=None):
user = MyUser.objects.get(pk=pk)
if request.method == "POST":
form = PasswordChangeForm(user=user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
return render(request, "nurse/change_password.html", {"user_id":user.id}) // passing user_id as context
I can see this value in my html file
<div class="form-group">
<label class="control-label allign col-sm-3" > {{user_id}} Old Password </label> // user_id is giving the right value
</div>
But when i try to fetch the same in action than it is not working:
<form class="form-horizontal login-box2" action="{% url 'booking:change_password' user_id %}" role="form" method="post"> // not getting user_id here
<div class="form-group">
<label class="control-label allign col-sm-3" > {{user_id}} Old Password </label> // getting user_id here
</div>
<div class="form-group">
<li> <button type="submit" class="btn btn-primary f-w-b f-s-18">Change</button> </li>
</div>
</form>
Can anyone tell me what i am doing wrong?
Thanks
EDITED
adding urls.py code:
url(r'^change_password/(?P<pk>[0-9]+)/$',views.change_password,name='change_password'),

Flask Python submit button

I am trying to create a page to register users but the submit button in my bootstrap form isn't working. When I hit the submit button, I get a bad request error. Here is the code in my python file:
#app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
if not request.form['username']:
error = 'You have to enter a username'
elif not request.form['email'] or '#' not in request.form['email']:
error = 'You have to enter a valid email address'
elif not request.form['password']:
error = 'You have to enter a password'
elif get_user_id(request.form['username']) is not None:
error = 'The username is already taken'
else:
print(request.form['username'])
db = get_db()
db.execute('INSERT INTO user (username, email, pw_hash) VALUES (?, ?, ?)',
[request.form['username'], request.form['email'],
generate_password_hash(request.form['password'])])
db.commit()
flash('You were successfully registered and can login now')
return render_template('control.html')
return render_template('register.html')
also i have a html file register.html:
{% extends 'layout.html' %}
{% block title %}Sign-up{% endblock title %}
{% block body %}
<div class="container">
<form class="form-register" role="form" method="post" action="{{ url_for('register') }}">
<h2 class="form-register-heading">Please sign up</h2>
<label for="username" class="sr-only">Username</label>
<input type="username" id="inputUsername" class="form-control" value="{{ request.form.username }}" placeholder="Username" required autofocus>
<label for="email" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" value="{{ request.form.email }}" placeholder="Email address" required autofocus>
<label for="password" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required >
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign up</button>
</form>
</div>
{% endblock body %}
I can't find where I did it wrong, I'm new to python and flask!
Your input fields have no name attribute. This will cause all of your checks to result in KeyErrors. The first step is to add the attribute to each input.
<input name="username" type="text" id="inputUsername" class="form-control" value="{{ request.form.username }}" placeholder="Username" required autofocus>
Note that I also checked the type attribute as there is no username type. email and password are valid values, email being added in HTML5.
The next step will be to change how you check for the fields. If you only care about the presence of the field, in is the way to go.
if 'username' not in request.form:
If, however, you also want a truty value, the get method is what you want.
if not request.form.get('username'):

Categories

Resources