flask-nav not working with flask-bootstrap sample application - flask

I'm trying to recreate this sample app that is supplied with flask-bootstrap, but have run into an issue rendering the navbar. I get the error:
inja2.exceptions.UndefinedError: 'flask_nav.Nav object' has no attribute 'fronend_top'
The example app is here:
https://github.com/mbr/flask-bootstrap/tree/master/sample_app
And the flask-nav example is here:
http://pythonhosted.org/flask-nav/getting-started.html#rendering-the-navbar
As far as I can tell I'm doing what seems to be correct, but I guess the nav isn't being passed to the web page context? Not sure.
Here is my server.py
from flask import Blueprint, render_template, flash, redirect, url_for
from flask_bootstrap import __version__ as FLASK_BOOTSTRAP_VERSION
from flask_bootstrap import Bootstrap
from flask_nav.elements import Navbar, View, Subgroup, Link, Text, Separator
from markupsafe import escape
from flask_nav import Nav
from forms import SignupForm
from flask import Flask
#from nav import nav
frontend = Blueprint('frontend', __name__)
# We're adding a navbar as well through flask-navbar. In our example, the
# navbar has an usual amount of Link-Elements, more commonly you will have a
# lot more View instances.
nav = Nav()
nav.register_element('frontend_top', Navbar(
View('Flask-Bootstrap', '.index'),
View('Home', '.index'),
View('Forms Example', '.example_form'),
View('Debug-Info', 'debug.debug_root'), ))
# Our index-page just shows a quick explanation. Check out the template
# "templates/index.html" documentation for more details.
#frontend.route('/')
def index():
return render_template('index.html', nav=nav)
app = Flask(__name__)
app.register_blueprint(frontend)
bootstrap = Bootstrap(app)
nav.init_app(app)
app.run(debug=True)
And here is the line that is throwing the error in my base.html
{% block navbar %}
{{nav.fronend_top.render()}}
{% endblock %}
Thanks for any help!

I was able to use this:
https://github.com/mbr/flask-nav/blob/master/example/init.py
and this:
http://pythonhosted.org/flask-nav/getting-started.html#rendering-the-navbar
to create a simplified version which worked. I started with the create_app method from the init example, which worked, then removed the method in the example below. Maybe it had to do with it being a blueprint? so it didn't have the nav object?
from flask import Blueprint, render_template, flash, redirect, url_for
from flask_bootstrap import __version__ as FLASK_BOOTSTRAP_VERSION
from flask_bootstrap import Bootstrap
from flask_nav.elements import Navbar, View, Subgroup, Link, Text, Separator
from markupsafe import escape
from flask_nav import Nav
from forms import SignupForm
from flask import Flask
#from nav import nav
app = Flask(__name__)
nav = Nav()
topbar = Navbar('',
View('Home', 'index'),
)
nav.register_element('top', topbar)
# not good style, but like to keep our examples short
#app.route('/')
def index():
return render_template('index.html')
#app.route('/products/<product>/')
def products(product):
return render_template('index.html', msg='Buy our {}'.format(product))
#app.route('/about-us/')
def about():
return render_template('index.html')
# Shows a long signup form, demonstrating form rendering.
#app.route('/example-form/', methods=('GET', 'POST'))
def example_form():
form = SignupForm()
if form.validate_on_submit():
flash('Hello, {}. You have successfully signed up'
.format(escape(form.name.data)))
# In a real application, you may wish to avoid this tedious redirect.
return redirect(url_for('.index'))
return render_template('signup.html', form=form)
nav.init_app(app)
bootstrap = Bootstrap(app)
app.run(debug=True)

Are you trying this with flask-boostrap4? If so, i found that it's Navbar Renderer is broken and causes the same error you found. Using flask-boostrap v3 along with BS 3 seems to fix it.

Related

Flask-Babel: get_locale() seems to be not working

I'm configuring flask-babel to translate an html page from English as base language to Portuguese as translated language. However, no changes at get_locale() reflected in a different language.
These are my current relevant codes:
app.py:
from flask import Flask, render_template
from flask_babel import Babel
from flask_babel import gettext as _
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'pt'
babel = Babel(app)
babel.init_app(app)
def get_locale():
return 'en'
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
html:
<!DOCTYPE html>
<html lang="en">
<body>
<h1>{{ _('Word') }}</h1>
</body>
</html>
Switching manually app.config['BABEL_DEFAULT_LOCALE'] = 'pt' seems to show equivalent translated word as written in '.po' file and then compiled, and switching ['BABEL_DEFAULT_LOCALE'] to 'en' and get_locale() to 'pt' seems to show the untranslated word again. In other words, I think my 'messages.mo' file is working as intended. It's as if the get_locale() function is getting ignored.
I'm using flask 2.2.2 and flask-babel 3.0.0, thus, I didn't insert #babel.localeselector as it seems it's not needed (and returns unrecognized decorator when inserted).
Thanks in advance
----- ANSWER -----
Using babel.init_app(app, locale_selector=get_locale) didn't work for the first few times, until I wrote my code in the following order: babel initialization, then get_locale() function, then init_app.
from flask import Flask, render_template
from flask_babel import Babel
from flask_babel import gettext as _
app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
babel = Babel(app)
def get_locale():
return 'en'
babel.init_app(app, locale_selector=get_locale)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
Did you check documentation?
You have to set locale_selector to be able use own function:
...
def get_locale():
return 'en'
babel = Babel(app)
babel.init_app(app, locale_selector=get_locale)
...

Why do the routes "/login" and "/register" not work?

My Flask application is not recognizing/using the two defined routes in auth.py, how come?
File structure
Error Msg:
Not Found: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Routes
http://127.0.0.1:5000/home (WORKS)
http://127.0.0.1:5000/profile (WORKS)
http://127.0.0.1:5000/login (DOES NOT WORK)
http://127.0.0.1:5000/register (DOES NOT WORK)
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/home")
def home():
return render_template("index.html")
#app.route("/profile")
def profile():
return render_template("profile.html")
auth.py
from flask import current_app as app, render_template
#app.route("/login")
def login():
return render_template("login.html")
#app.route("/register")
def register():
return render_template("register.html")
You can't register routes to current_app, instead you have to use a class called Blueprint which is built exactly for this purpose (splitting application into multiple files).
app.py
from flask import Flask, render_template
from auth import auth_bp
app = Flask(__name__)
# Register the blueprint
app.register_blueprint(auth_bp)
#app.route("/home")
def home():
return render_template("index.html")
#app.route("/profile")
def profile():
return render_template("profile.html")
auth.py
from flask import Blueprint, render_template
# Initialize the blueprint
auth_bp = Blueprint('auth', __name__)
#auth_bp.route("/login")
def login():
return render_template("login.html")
#auth_bp.route("/register")
def register():
return render_template("register.html")
See https://flask.palletsprojects.com/en/2.0.x/blueprints/ for more information.
It seems like you have at least two files in which you have these routes. In your app.py file you have /home and /profile, they both work. They work because you initialised the Flask application over there.
Flask offers Blueprints to split up your application. You could create a blueprint called auth for example.
There is a specific tutorial on this subject as well.
I suggest moving the initialisation of the app variable to the __init__.py file and creating a create_app() method that returns app. In this method you can register your blueprints as well.
This method would look like:
def create_app():
app = Flask(__name__)
from . import app as application, auth
app.register_blueprint(auth.bp)
app.register_blueprint(application.bp)
return app
Your auth.py file, for example, would look like:
from flask import Blueprint, render_template
bp = Blueprint('auth', __name__)
#bp.route("/login")
def login():
return render_template("login.html")
#bp.route("/register")
def register():
return render_template("register.html")

How to go from one page to another in django

I'm new to Django and python (infact my first language which I've only been learning for 3 months)
I'm creating this website using Django and I'm not able to go from one page to another using the href tag. it throws at me a 404 error saying "current path didn't match any of these"
This is my code
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import off
# Create your views here.
def homepage(request):
return render(request=request,
template_name='main/home.html',
context={'toll' : off.objects.all})
def secondpage(request):
return render(request = request,
template_name = 'main/next.html')
main/urls.py
from django.urls import path
from . import views
app_name = 'main'
urlpatterns = [
path('',views.homepage,name='homepage'),
path('',views.secondpage,name='secondpage')
]
templates/mains/home.html
<div class="topnav">
Link
Link
Link
</div>
I also request the helper to simply it for me as I wouldn't be able to handle complex and advanced python terminology
Thanks In Advance From a Friend
Arvind
I think you should read this to start with Django.

Can I print just the content of a html template in django?

I am using Django with python to create a web application, I am a beginner in this. I hope that you can help me.
I want to print this page by clicking a button.
Now, I am just trying to generate the pdf first.
I want just to print the content, like that
I tried these functions.
#views.py
from django.views.generic.detail import DetailView
from MagasinProject.views import PdfMixin
from MagasinProject.utils import generate_pdf, render_to_pdf_response, pdf_decorator
from django.contrib.auth.models import User
from django.shortcuts import render
def test_view(request):
resp = HttpResponse(content_type='application/pdf')
result = generate_pdf('demande/demande.html', file_object=resp)
return result
#urls.py
from django.urls import path
from . import views
from django.conf.urls import url
urlpatterns=[
path('demande',views.index, name='demande'),
url(r'^test_view$', views.test_view),
]
This is what I got
You can print the HTML page with a print button like this (see w3schools):
<button onclick="window.print()">Print this page</button>

ValueError: server must be a Flask app or a boolean

I'm trying to work through the simplest dashboard example in the django-plotly-dash documentation, but I'm consistently getting the ValueError above.
For the code below, assume the django project name is django_project and the django app name is dashboard.
My ROOT_URLCONF at django_project/urls.py has the following relevant code:
import dashboard.dash_app
from dashboard.views import test_view
urlpatterns = [
...
path('dashboard/', test_view, name='test_view'),
path('django_plotly_dash/', include('django_plotly_dash.urls')),
]
My dashboard app view, located at dashboard/views.py is as follows:
from django.shortcuts import render
def test_view(request):
return render(request, 'dashboard/main.html')
The main.html template is as follows:
from django.shortcuts import render
def test_view(request):
return render(request, 'dashboard/main.html')
{% load plotly_dash %}
{% plotly_app name="SimpleExample" %}
Finally, the DjangoDash app instance is created in a file called dashboard/dash_app.py. As shown earlier, this module is imported in django_project/urls.py, as above. Code is as follows:
import dash
import dash_core_components as dcc
import dash_html_components as html
from django_plotly_dash import DjangoDash
app = DjangoDash('SimpleExample')
app.layout = ...
#app.callback(...)
def callback_color(...):
...
During the debugging process, the only other seemingly relevant information that I have is that the base_pathname is '/django_plotly_dash/app/SimpleExample/'
Any other ideas?
This is caused by the recent update to Dash version 1.0 on 2019-06-20. The Dash class now checks to ensure that server is either boolean or an instance of Flask. Since django plotly_dash uses it's own PseudoFlask object, it fails this check and it is incompatible with Dash 1.0 and will need to be updated for use with the current Dash version.
I experienced the same problem today. Using an older version of Dash (0.43.0) solved it for me.