I'm using Python 2.7 and Flask with Bootstrap:
When I log in my website, the page 405 Method Not Allowed shows after submitting my username and password. They do exist in the database and the page should at least show an error message.
The login function in my init.py:
#app.route('/login/', methods = ['GET','POST'])
def login():
try:
c, conn = connection()
error = None
if request.method == 'POST':
data = c.execute("SELECT * FROM users WHERE username = (%s)",
thwart(request.form['username']))
data = c.fetchone()[2]
if sha256_crypt.verify(request.form['password'], data):
session['logged_in'] = True
session['username'] = request.form['username']
flash("Welcome "+str(session['username'])+"! You are now logged in.")
return redirect(url_for("dashboard"))
else:
error = "Invalid credentials, try again."
gc.collect()
return render_template('login.html', error = error)
except Exception as e:
flash(e)
error = "Invalid credentials, try again."
return render_template('login.html', error = error)
And here is my login.html file:
{% extends "header.html" %}
{% block body %}
<body>
<div class="container">
<br>
<h4>Please Login:</h4>
<br>
<form action="" class="form-inline" method="post">
<input type="text" class="form-control" placeholder = "Username" name="username" value="{{request.form.username}}">
<input type="password" class="form-control" placeholder = "Password" name="password" value="{{request.form.password}}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}</p>
{% endif %}
<div class="container">
<br>
<p>No account? <a href='/register'>Register here</a>.</p>
<br>
{% for paragraph in Body_info %}
<p>{{ paragraph }}</p>
{% endfor %}
</div>
</div>
</body>
{% endblock %}
Related
Under views.py
def addcomments(request):
comment_text = request.POST.get('comment')
user_id = request.POST.get('user_id')
name = request.POST.get('name')
email = request.POST.get('email')
comment = Comment.objects.create(user_id=user_id, body=comment_text, name=name, email=email)
comment.save()
return HttpResponseRedirect(reverse('users:detail', args=(user_id, )))
this one, from detail.html
{% extends 'base.html' %}
{% block title %}
{{ user.user_fname }} {{ user.user_lname }}
{% endblock %}
{% block content %}
{% if error_message %}
<p class="alert alert-danger">
<strong>{{error_message}}</strong>
</p>
{% endif %}
<div class="row">
<div class="col-lg-6">
<div class="mb-5">
<h1>{{ user.user_fname }} {{ user.user_lname }}</h1>
<p class="text-muted">{{ user.user_email }}</p>
<p>Position: {{ user.user_position }}</p>
</div>
<div class="img-responsive">
<img src="/users/media/{{user.user_image}}" alt="profile_user" class="img-rounded" width="300">
<!-- ito yung hinahanap ng search engine-->
</div>
<div class="btn-group mt-5">
Delete
Edit
Back
</div>
</div>
<div class="col-lg-6">
<h2>Comment</h2>
<p class="text-muted"> Number of comment : {{ comments_count }}</p>
{% if comments_count > 0 %}
{% for comment in comments %}
{% if comment.active %}
<p><strong>{{comment.name}}</strong> : {{comment.body}}</p>
{% endif %}
{% endfor %}
{% endif %}
<hr>
<br><br><br><br><br><br>
<form action="{%url 'users:addcomments'%}" method="post">
{% csrf_token %}
<div class="form-group">
<label>Comment</label>
<textarea name="comment" id="comment" cols="30" rows="5" class="form-control" required placeholder="Enter your comment here ..."></textarea>
</div>
<br>
<input type="text" name="name" id="name" value="{{ user.user_lname }}">
<input type="text" name="lname" id="lname" value="{{ user.user_fname }}">
<input type="text" name="email" id="email" value="{{ user.user_email }}">
<br><br><br><br>
<button type="submit" class="btn btn-sm btn-primary">Add Comment</button>
</form>
</div>
</div>
{% endblock %}
this one for url.py
path('addcomments', views.addcomments, name='addcomments'),
I am having the error message,
IntegrityError at /users/addcomments
(1048, "Column 'user_id' cannot be null")
During handling of the above exception ((1048, "Column 'user_id' cannot be null")), another exception occurred:
from 404
users\views.py, line 146, in addcomments
comment = Comment.objects.create(user_id=users_id, body=comment_text, name=name, email=email) …
Local vars
Variable Value
comment_text
'wwerwr'
email
'HeavyRain#gmail.com'
name
'Heavy'
request
<WSGIRequest: POST '/users/addcomments'>
user_id
None
the heavyrain details, ignore it, was trying stuffs
this one for detail detail is working fine properly, detail is on left side of the page, while addcomments is on the right side of the same page
#login_required(login_url='/users/login')
def detail(request, profile_id):
try:
user = User.objects.get(pk=profile_id)
comments = Comment.objects.filter(user_id=profile_id)
comments_count = Comment.objects.filter(user_id=profile_id).count()
except User.DoesNotExist:
raise Http404("Profile does not exist")
return render(request, 'UI/detail.html', {'user': user, 'comments': comments, 'comments_count': comments_count})
You don't have an user_id field in your html form that's why it becomes None or null and since you don't allow your user_id to be none (don't allow it to be none) django fails to create it. I suggest you get rid of the user_id in the creation and search for a user with that exact unique username that posted the form with
user = request.user
comment = Comment.objects.create(user=user, body=comment_text, name=name, email=email)
I'm sorry but use a model form. It's the MOST appropriate solution. It will manage rendering your form in html and ensuring data is clean and validated.
from django import forms
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = [...]
Please see further information in the documentation.
https://docs.djangoproject.com/en/4.1/topics/forms/modelforms/
Models.py
class ContactForm(models.Model):
name = models.CharField(max_length=50)
subject = models.CharField(max_length=200)
email = models.EmailField()
message = models.TextField()
def __str__(self):
return self.name
views.py
def contact(request):
if request.method == "POST":
name = request.POST.get('name')
subject = request.POST.get('subject')
email = request.POST.get('email')
message = request.POST.get('message')
ContactForm.objects.create(
name = name,
subject = subject,
email = email,
message = message
)
return render(
request,
'blog/contact.html',
{
'msg':'Details have been saved. We will get back to you.'
}
)
else:
return render(request, 'blog/contact.html')
contact.html
{% extends 'blog/base.html' %}
{% block content %}
<div class="container wrap mb-5" style="margin-top: 100px">
<h2 class="text">Contact Us</h2>
<form action="{% url 'contact' %}" method="POST">
{% csrf_token %}
<input type="text" placeholder="Enter Your Name" name="name">
<input type="text" placeholder="Subject" name="subject">
<input type="email" placeholder="Enter Your Email" name="email">
<input type="message" placeholder="Write Your Message" name="msg">
<input type="submit" value="Send" name="Submit">
</form>
{% if msg %}
<div class="alert alert-success">
{{ msg }}
</div>
{% endif %}
</div>
{% endblock %}
This error occured while I click on the submit button.
It shows IntegrityError at /contact/ NOT NULL constraint failed: blog_contacts.message.
I see that in the html, for the message input, the name tag is 'msg' and in view it is request.POST.get('message'). Hence it cannot find that post variable. Also there is no such input type as 'message', So you can change that too, The code for the line now looks like
<input type="text" placeholder="Write Your Message" name="message">
Also getting straight post objects is not recommended, it leaves you open to security holes. You should use Django forms to clean data before using user input. Check out the official documentation for more help
https://docs.djangoproject.com/en/3.0/topics/forms/
I'm new to python and CS so this question might be a bit too easy. Thanks for your help I'm getting an error:
Bad Request
The browser (or proxy) sent a request that this server could not understand.
After implementing a new html template and python function:
#app.route("/register", methods=["GET", "POST"])
def register():
"""Register user."""
session.clear()
if request.form["name"] == "" or request.form["password"] == "":
return render_template("apology.html")
elif request.form["password"] != request.form["confirmation"]:
return render_template("apology.html")
hash = pbkdf2_sha256.hash("password")
do.execute("INSERT INTO finance (name, password) VALUES(:name, :password)",
name=request.form.get["name"], hash=hash)
session["user_id"] = rows[0]["id"]
return redirect(url_for("index"))
{% extends "layout.html" %}
{% block title %}
Register
{% endblock %}
{% block main %}
<form action="{{ url_for('register') }}" method="post">
<fieldset>
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="username" placeholder="Username" type="text"/>
</div>
<div class="form-group">
<input class="form-control" name="password" placeholder="Password" type="password"/>
</div>
<div class="form-group">
<input class="form-control" name="confirmation" placeholder="Confirm Password" type="password"/>
</div>
<div class="form-group">
<button class="btn btn-default" type="submit">Register</button>
</div>
</fieldset>
</form>
{% endblock %}
First you should check if the request type is 'POST', after that you check all the conditions. Do like below to resolve the issue:
#app.route("/register", methods=["GET", "POST"])
def register():
"""Register user."""
session.clear()
if request.method == 'POST':
if request.form["name"] == "" or request.form["password"] == "":
return render_template("apology.html")
elif request.form["password"] != request.form["confirmation"]:
return render_template("apology.html")
hash = pbkdf2_sha256.hash("password")
do.execute("INSERT INTO finance (name, password) VALUES(:name, :password)",
name=request.form.get["name"], hash=hash)
session["user_id"] = rows[0]["id"]
return redirect(url_for("index"))
else:
// you can render the template to be shown for registration.
I'm handling input file in my project and passing processed text to another html for user approvement
def vm_to_csv_upload(request):
if request.method == "POST":
some code here
br_work_string = re.sub('\\n', '<br>', work_string)
page_text = 'Here\'s what gonna be uploaded to crowdin:<br><br><br>' + br_work_string + '<br><br><br>Is that okay?'
return render(request, 'upload_crowdin_check.html', {'page_text': page_text, 'csv_text': work_string})
On this page i show passed data:
<body>
<div id="text_check">
{% autoescape off %}
{{ page_text }}
{% endautoescape %}
</div>
<form action="/crowdin_approve/" method="POST" value={{ csv_text }} id="csv">
{% csrf_token %}
<input type="submit" class="btn btn-xs btn-danger" value="Okay">
</form>
</body>
And trying to pass it to another view to process it again.
def crowdin_approve(request):
if request.method == "POST":
return HttpResponse(request.POST)
else:
return HttpResponse('nope')
But only thing i get is csrfmiddlewaretoken. What am i doing wrong? How should i pass {{ csv_text }} value to view? Thx.
You can pass the content of csv_text using an hidden input field:
<form action="/crowdin_approve/" method="POST" id="csv">
{% csrf_token %}
<input type="hidden" name="csv_text" value="{{ csv_text }}">
<input type="submit" class="btn btn-xs btn-danger" value="Okay">
</form>
Then you can access it in the view this way:
def crowdin_approve(request):
if request.method == "POST":
csv_text = request.POST.get('csv_text', None)
I'm making a webpage where I login and add people to an address book. Once I login and click on the "add address" button, I'm redirected back to the login page with the following url:
http://localhost:8000/xcard/login/?next=/xcard/add_address/
If I login again I can get to account page, address book, and then add_address book page without being caught in the login loop. I can logout and login and add addresses without relogin in twice. But the first time I ever login I have to do it twice. Not sure if it's a problem with the login or the add address code.
Views.py
class LoginView(View):
def get(self, request):
''' if user is authenticated '''
if request.user.is_authenticated():
return render(request, 'xcard/account.html')
else:
return render(request, 'xcard/login.html')
def post(self, request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
state = "The email or password is incorrect"
if user is not None:
login(request, user)
return HttpResponseRedirect('/xcard/account/')
else:
return render(request, 'xcard/login.html', {'state':state})
class AddAddressView(View):
def get(self,request):
address_form = AddressForm()
friend_form = FriendForm()
return render(request, 'xcard/add_address.html', {'friend_form':friend_form, 'address_form':address_form})
def post(self,request):
address_form = AddressForm(request.POST)
friend_form = FriendForm(request.POST)
if address_form.is_valid() and friend_form.is_valid():
new_address = address_form.save()
new_friend = friend_form.save(commit=False)
new_friend.address = new_address
new_friend.save()
return HttpResponseRedirect('/xcard/address_book')
else:
return render(request, 'xcard/add_address.html', {'state' : "Failed", 'friend_form':friend_form, 'address_form':address_form})
Templates:
address_book.html
{% include "xcard/header.html" %}
{% block main %}
<div class="container">
<h3 class="text-info"><u>Your Account</u></h3>
Add
Import
</div>
{% endblock %}
Templates:
login.html
{% extends "xcard/base.html" %}
{% block main %}
<div class="container">
<div class="row space">
<p class="text-center lead text-warning">
Login page</p>
<p class="text-center text-info">Trusted worldwide!</p>
</div>
<div class="row">
<div class="span offset4">
<form class="well" action="/xcard/login/" method="post">
{% csrf_token %}
<p class="lead">Sign In</p>
<fieldset class="login_page">
<p class="text-error"><strong>{{ state }}</strong></p>
<label class="control-label" for ="inputIcon">Email</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-user"></i></span>
<input type="text" class="span3" id="ernainputIcon" required name="username" placeholder="Username...."/><br/><br/>
</div>
</div>
<label>Password</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on"><i class="icon-lock"></i></span>
<input type="password" class="span3" id="inputIcon" required name="password" placeholder="Password...."/><br/><br/><br />
</div>
</div>
<button class="btn btn-primary">Sign In</button>
Not a user?
Sign up
</fieldset>
</form>
</div>
</div>
</div>
{% endblock %}
I just found this in my urls.py
url(r'^add_address/$', login_required(AddAddressView.as_view(), login_url='/xcard/login/')),
Maybe this is causing the problem? But why doesn't it register that I'm already logged in?
first do the correction in AddAddressView function. update line
return render(request, 'xcard/add_address.html', {'friend_form':friend_form, 'address_form':address_form})
it will work
This was my solution - logout before you try to authenticate.
This issue happened to me when users were logging in and logging back in with a different username.
import django.contrib.auth as djangoAuth
djangoAuth.logout(request) # logout
user = djangoAuth.authenticate(username=username, password=password) # login