ValueError: server must be a Flask app or a boolean - django

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.

Related

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.

flask-nav not working with flask-bootstrap sample application

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.

Django Caching on front-end

I was working with 2 applications that are within a DJango project: "customer" and "vendors". Each application has a HTML file named "testindex.html".
Whenever I typed:
http://myhost/customer/basic_info
the correct page would show up
If I typed
http://myhost/vendors/basic_info
the page from http://myhost/customer/basic_info would show up
I found out that it was due to caching (since both applications use "testindex.html"). So again, "testindex.html" is caching.
How can one get around this problem?
TIA
Details are listed below. I have the following views defined:
urls.py for the project
urlpatterns = [
... snip ...
url(r'^customer/', include('libmstr.customer.urls')),
url(r'^vendors/', include('libmstr.vendors.urls')),
]
views.py for customer
from django.shortcuts import render
def basic_info(request):
return render(request, 'testindex.html', {})
views.py for vendors
from django.shortcuts import render
def basic_info(request):
return render(request, 'testindex.html', {})
urls.py for customers
from django.conf.urls import url
from . import views
# list of templates
app_name = 'customer'
urlpatterns = [
url(r'^basic_info/$', views.basic_info, name='basic_info'),
]
urls.py for vendors
from django.conf.urls import url
from . import views
# list of templates
app_name = 'vendors'
urlpatterns = [
url(r'^basic_info/$', views.basic_info, name='basic_info'),
]
It sounds like you have two templates, customers/templates/testindex.html and vendors/templates/testindex.html.
When you call render(request, 'testindex.html', {}), the app directories template loader searches the templates directory for each app in INSTALLED_APPS, and stops the first time it finds a match. If customers is above vendors in INSTALLED_APPS, then it will always use the customers template.
For this reason, Django recommends that you name your templates customers/templates/customers/testindex.html and vendors/templates/vendors/testindex.html, and change your views to use customers/testindex.html and vendors/testindex.html. This way you avoid clashes.

Troubleshooting error when using markdown filter in Django template

When using the Markdown libraries I seem to get the following error:
Error in 'markdown' filter: Django does not support versions of the
Python markdown library < 2.1.
As an example, it occurs on a tag such as:
{{ticket.get_description|markdown:"safe,footnotes,tables"}}
The get_description function is defined in the Ticket model. We've upgraded to Django 1.5 recently and the code was written pre Django 1.4. I've also upgraded the Markup library to 2.3.1 but the problem still persists. I've also cleared old .pyc files, just to be sure.
From what I've read, the django.contrib.markup libraries have been deprecated. So, what would the suggested solution/alternative be?
one idea is to install markdown2 library of python see here
then you create your decorator
import markdown2
.. all other imports needed..
register = template.Library()
#register.filter(is_safe=True)
#stringfilter
def markdown2(value):
return mark_safe(markdown2.markdown(force_unicode(value),safe_mode=True,enable_attributes=False))
then you use it
{% load myapp_markup %}
{{ value|markdown2 }}
code is adpated (and not tested) from here
Just an update:
My decorator looks like this:
import markdown2
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
register = template.Library()
#register.filter(is_safe=True)
#stringfilter
def convertTxt(value):
return mark_safe(markdown2.markdown(force_unicode(value)))
register.filter('convertTxt', convertTxt)
Also, I've noticed that it is not prudent to name your module or your method markdown2 :)

How can i redirect from one domain to another in django app?

Normally i would do it with .htaccess but django doesn't have it.
So what is the best way and what is the code for it to redirect from www.olddomain.com to www.newdomain.com?
NOTE: we are not using Apache, but Gunicorn
thanx!
The best way to do this is still with your web server rather than Django. This will be much quicker and more efficient than doing it with Django.
Check out this question for more info.
UPDATE
If you really want to do it within django then edit your url conf file (which manages django's url dispatcher) to include the following at the top -
from django.views.generic.simple import redirect_to
urlpatterns = patterns('',
(r'^.*$', redirect_to, {'url': 'http://www.newdomain.com'}),
)
For more info check out the documentation.
import urlparse
from django.http import HttpResponseRedirect
domain = request.GET['domain']
destination = reverse('variable_response',args=['Successful'])
full_address = urlparse.urljoin(domain, destination)
return HttpResponseRedirect(full_address)
i had the same problem so i wrote this and it worked perfectly for me, maybe someone else needs it too:
urlpatterns += [ # redirect to media server with same path
url(r'^media/', redirectMedia),
]
and using this function to redirect:
from urllib.request import urlopen
from django.http import HttpResponse
def redirectMedia(request):
x = urlopen("http://www.newdomain.com" + request.path)
return HttpResponse(x.read())
enjoy it!
For Django >= 2.0 , the easier solution is to use RedirectView
For example in urls.py :
from django.views.generic.base import RedirectView
urlpatterns = [
path('my_ext_uri', RedirectView.as_view(url='https://YOUR_EXTERNAL_URL')),
]
[Side note]
As mentioned in Aidan's answer , it would be better to redirect requests which will be handled by different services at web server gateway, rather than at (Python/Django) application server.
I ended up doing it using heroku and spinning up 1 web dyno (which is free).
#views.py
def redirect(request):
return render_to_response('redirect.html')
#redirect.html
<html>
<head>
<title>Blah</title>
<meta http-equiv="refresh" content="1;url=http://www.example.com">
</head>
<body>
<p>
Redirecting to our main site. If you're not redirected within a couple of seconds, click here:<br />
example.com
</p>
</body>
</html>
Simple as that. Can find the same example here.
An alternative to catherine answer, updated to Python 3 is:
from django.contrib.sites.shortcuts import get_current_site
from urllib.parse import urljoin
from django.http import HttpResponseRedirect
NEW_DOMAIN = 'www.newdomain.com'
Put in each view:
def myView(request, my_id):
if request.META['HTTP_HOST'] != NEW_DOMAIN:
# remove the args if not needed
destination = reverse('url_tag', args=[my_id])
full_address = urljoin(DOMAIN, str(destination))
return HttpResponseRedirect(full_address)
# your view here
The url_tag is the one defined in urlpatterns.
I ended with simple solution:
return HttpResponse(f"<script>location.replace('https://example.com/');</script>")
It works if user don't disable scripts in webbrowser
You could do it simply adding the redirect in the value 'urlpattens' found in 'urls.py'. Hope it helps. The reference is source.
from django.shortcuts import redirect
urlpatterns = [
path('old-path/', lambda request: redirect('new-path/', permanent=False)),
]