0
votes

I have designed admin page in flask web framework using python. And I deployed my admin app on a shared hosting server. I am getting a problem with redirecting to next URL. That is when I click on login button it gives 404 URL not found error. Also on error page in URL window, it appends the previous URL. But the thing is it works perfectly on my local machine. I don't know what's the problem. EDIT: Basically it dont go to next page as it is redirected to "index" after clicking on Login This is my flask app code.

from flask import Flask, render_template, redirect, url_for, request
from flask_bootstrap import Bootstrap
from flask_wtf import FlaskForm 
from wtforms import StringField, PasswordField, BooleanField
from wtforms.validators import InputRequired, Email, Length
from flask_sqlalchemy  import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import LoginManager, UserMixin, login_user,  login_required, logout_user, current_user
from werkzeug import secure_filename
import sqlite3
import hashlib
import os
import models as dbHandler
import stringtolist as stol 

UPLOAD_FOLDER = 'static/images/project_img/'

adminapp = Flask(__name__)
application = adminapp
adminapp.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
adminapp.config['SECRET_KEY'] = 'Thisissupposedtobesecret!'
adminapp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
bootstrap = Bootstrap(adminapp)
db = SQLAlchemy(adminapp)
login_manager = LoginManager()
login_manager.init_app(adminapp)
login_manager.login_view = 'login'


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(15), unique=True)
    email = db.Column(db.String(50), unique=True)
    password = db.Column(db.String(80))

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

class LoginForm(FlaskForm):
    username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
    password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])
    remember = BooleanField('remember me')

class RegisterForm(FlaskForm):
    email = StringField('email', validators=[InputRequired(), Email(message='Invalid email'), Length(max=50)])
    username = StringField('username', validators=[InputRequired(), Length(min=4, max=15)])
    password = PasswordField('password', validators=[InputRequired(), Length(min=8, max=80)])

@adminapp.route('/')
@login_required
def index1():
    return render_template('index1.html', name=current_user.username)

@adminapp.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()

    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user:
            if check_password_hash(user.password, form.password.data):
                login_user(user, remember=form.remember.data)
                return redirect(url_for('index1'))    #After Login successfully browser needs to redirect to index1 page which dashboard page.

        return '<h1>Invalid username or password</h1>'
        #return '<h1>' + form.username.data + ' ' + form.password.data + '</h1>'

    return render_template('login.html', form=form)


@adminapp.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('login'))

if __name__ == '__main__':
    adminapp.run(debug=True)

EDIT2: okay so here the minimal code for login user. When I hit the Login button it appends the url from where it is redirecting. Like this

domainname.com/login -> The URL in URL window before login

domainname.com/login -> When I hit login button it redirects to this URL again,

it should go to index1 like this

domainname.com/index1

This is my

login.html

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block title %}
Login
{% endblock %}

{% block styles %}
{{super()}}
<link rel="stylesheet" href="{{url_for('.static', filename='../static/css/signin.css')}}">
{% endblock %}

{% block content %}
    <div class="container">

      <form class="form-signin" method="POST" action="/login">
        <h2 class="form-signin-heading">Please sign in</h2>
        {{ form.hidden_tag() }}
        {{ wtf.form_field(form.username) }}
        {{ wtf.form_field(form.password) }}
        {{ wtf.form_field(form.remember) }}
        <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
       <!--  <button class="btn btn-lg btn-primary btn-block" onclick="location.href='{{ url_for('signup') }}'" type="button">Sign Up</button> -->
      </form>

    </div> <!-- /container -->
{% endblock %}
1
It isn't totally clear what the root cause of the error is. Can you simplify your code example to the minimum code which is causing a problem? It may be helpful for us to see the contents of login.html as well. Can you also share the specific paths that the browser is attempting to redirect to (which is causing a 404?)poundifdef

1 Answers

2
votes

Your code works for me when I go to your demo website. I think the mistake you are making is understanding what url_for('index1') does.

You define a route like so:

@adminapp.route('/')
@login_required
def index1():
    return render_template('index1.html', name=current_user.username)

In this case, the route is /. The name of the method is index1. The route is not /index1. So if you are trying to go to /index1 then it will give you a 404 error because that route does not exist.

The url_for() takes a method name as input and returns a route as output. In this case, the name of the method is "index1", and the output is "/" because that is the actual HTTP route that you have defined.