Django, trying to change the class attribute of an extended nav bar - django

I created a "base.html" template to hold my nav bar and other elements that are recurrent on my website.
When I extend this template and put values into my blocks one of them doesn't want to work properly.
In my code I try to set the class value of my nav element to "active" depending on which page I'm in (it might not be the best solution). This block never works.
Thank you for your help :)
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^addProduct/$', views.addProduct, name='addProduct'),
]
views.py
def index(request):
latest_product_list = Product.objects.all().order_by('-id')[:5]
return render(request, 'main/index.html', {'latest_product_list': latest_product_list})
def addProduct(request):
# Do things
return render(request, 'main/add_product.html', {'form':form})
base.html
<!DOCTYPE html>
<html lang="fr">
<head>
#header informations
</head>
<body>
<div class="container-fluid">
<div class="row">
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
</div>
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="{% block navbar_class-index %}{% endblock %}">Index</span></li>
<li role="presentation" class="{% block navbar_class-addProduct %}{% endblock %}">Ajouter un produit</li>
</ul>
<div class="row" id="content">
{% block content %}{% endblock content %}
</div>
</div>
</body>
index.html
{% extends "base.html" %}
{% block navbar_class-index %}active{% endblock %}
{% block content %}
<div class="col-md-12">
## Here is my content
</div>
{% endblock content %}
add_product.html
{% extends "base.html" %}
{% block navbar_class-addProduct %}active{% endblock %}
{% block content %}
<div class="col-md-12">
<form action="{% url 'main:addProduct' %}" method="post">
{% csrf_token %}
<label> Entrez votre produit et cliquez sur Add Product.</label><br/><br/>
<label> Produit : </label>{{form.form_product_url}}
<input type="submit" value="Add Product" />
</form>
</div>
{% endblock content %}

I guess your base.html file is not in the correct folder !

Related

Flask.flash messages not available through extended template

I am having trouble with sending flashed messages to a route that extends its layout from another template. This message shows up just fine if use the message in the layout.html which makes me believe that rendering login.html first will render layout.html and use the flashed message there and not pass it to my /login route. How are you able to call this message in an extended template? I am using the jijna with syntax taken from here to be able to have the message variable available within my mainblock. Flask's documentation does not specify this either.
app.py
#app.route("/login", methods=["POST", "GET"])
def login():
# Forget any previous user
if session.get("user_id"):
session.pop("user_id")
if request.method == "POST":
# Create connection cursor
cursor = mysql.connection.cursor()
# Query database for email
cursor.execute("SELECT id, email, password FROM users WHERE email = %s", [request.form.get("email")])
row = cursor.fetchone()
print(row)
if row is None:
print("WHY")
flash("Invaid user")
return redirect("login")
My layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hoook - {% block title %}{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width">
<link href="/static/favicon-16x16.png" rel="icon">
<link href="/static/style.css" rel="stylesheet">
<!-- Scripts -->
<script src="https://kit.fontawesome.com/542c2d099e.js" crossorigin="anonymous"></script>
<script src="/static/mainJS.js"></script>
</head>
<body>
<div class="page-wrapper">
<header>
<nav class="main-navbar">
{% if request.path == "/login" %}
<div class="navbar-container login-container">
{% else %}
<div class="navbar-container">
{% endif %}
<div>
{% if request.path == "/login" %}
<img src="/static/hoook_logo_blue.png" alt="Hoook Logo" height="50" width="150">
{% else %}
<img src="/static/hoook_logo.png" alt="Hoook Logo" height="50" width="150">
{% endif %}
</div>
{% if request.path != "/login" %}
<div>
{% if session["user_id"] %}
{# change nav bar for logged in users #}
{% else %}
{# work on this nav bar for unlogged in users #}
{% if request.path == "/signup" %}
<a class="navbar-link" href="/login">Sign in</a>
{% endif %}
{% endif %}
</div>
{% endif %}
</div>
</nav>
</header>
</div>
<main>
{% if request.path == "/login" %}
<div class="top-container signup-container">
{% else %}
<div class="top-container">
{% endif %}
{% with messages = get_flashed_messages() %}
{% block main %}{% endblock %}
{% endwith %}
</div>
</main>
<footer>
</footer>
</body>
</html>
My login.html
{% extends "layout.html" %}
{% block title %}
Login
{% endblock %}
{% block main %}
<div class="login-div">
<div>
<h1 class="color-control">Sign in to Hoook</h1>
</div>
<div class="login-input-bx">
<form action="/login" method="post" autocomplete="off">
<div class="form-control login-form-control">
<label class="login-label color-control" for="email">Email address</label>
<input class="login-input" type="text" name="email" id="email" required autofocus>
</div>
<div class="form-control login-form-control">
<label class="login-label color-control" for="password">Password</label>
<input class="login-input" type="password" name="password" id="password" required readonly onfocus="this.removeAttribute('readonly')">
</div>
<button class="btn btn-login" type="submit">Sign in</button>
</form>
</div>
{% if messages %}
{% for msg in messages %}
<div class="flashed-messages-div">
<p class="signup-para" id="login-flashed-messages">Error: {{ msg }}</p>
</div>
{% endfor %}
{% endif %}
<div class="signup-link-div">
<p class="color-control signup-login-font">New to Hoook? <a class="signup-link-anchor" href="/signup">Create an account</a>.</p>
</div>
</div>
{% endblock %}
Update
I guess I could do something like make_response instead as seen here. and just use:
response = make_response(render_template("login.html", message = "Invalid user"), 302)
return response
However I am curious if there is a way to pass the flashed message through instead.
I have had the same issue. Instead of:
return redirect("login")
try with:
return render_template("login.html")
The flashed message works that way for me.

NoReverseMatch at /account/login/ (Trying to use Class based authentication views)

I am trying to use Django's class based authentication views and am getting the following error when attempting to access the login view:
NoReverseMatch at /account/login/
Reverse for 'register' not found. 'register' is not a valid view function or pattern name.
Error during template rendering
In template /Users/justin/Desktop/Programming/Python/django_book/social/website/account/templates/base.html, error at line 0
All authentication templates are stored at account/templates/registration/ and dashboard.html is stored at account/templates/account/, here is the code:
account/urls.py:
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', views.dashboard, name = 'dashboard'),
path('login/', auth_views.LoginView.as_view(), name = 'login'),
path('logout/', auth_views.LogoutView.as_view(), name = 'logout'),
]
login.html:
{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
<h1>Log-in</h1>
{% if form.errors %}
<p>
Your username and password didn't match.
Please try again.
</p>
{% else %}
<p>Please, use the following form to log-in. If you don't have an account register here</p>
{% endif %}
<div class="login-form">
<form action="{% url 'login' %}" method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<p><input type="submit" value="Log-in"></p>
</form>
</div>
{% endblock %}
base.html:
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title%}{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/base.css' %}">
</head>
<body>
<div id="header">
<span class = 'logo'>Bookmarks</span>
{% if request.user.is_authenticated %}
<ul class = 'menu'>
<li {% if section == "dashboard" %}class="selected"{% endif %}>
My dashboard
</li>
<li {% if section == "images" %}class="selected"{% endif %}>
Images
</li>
<li {% if section == "people" %}class="selected"{% endif %}>
People
</li>
</ul>
{% endif %}
<span class = 'user'>
{% if request.user.is_authenticated %}
Hello {{ request.user.first_name }},
Logout
{% else %}
Login
{% endif %}
</span>
</div>
<div id="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
Note sure if this is needed but the account/views.py with the dashboard view:
from django.contrib.auth.decorators import login_required
#login_required
def dashboard(request):
return render(request,
'account/dashboard.html',
{'section': 'dashboard'})
and dashboard.html:
{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
<h1>Dashboard</h1>
<p>Welcome to your dashboard.</p>
{% endblock %}
I am following the book 'Django 2 By Example' and at this point I believe I have directly copy and pasted the code from here (https://github.com/PacktPublishing/Django-2-by-Example/tree/master/Chapter04) to try and fix this error, but I am still getting. I should note that I am using Django 3.2.6 and am not sure if this is causing it. Thanks for any help with this.

Addind Datepicker_plus from bootstrap but button inactive

I add bootstrap_datepicker_plus to my code. In my template, I can see the calendar button on the right side of my field but when I click on the button nothing happened
try to modify settings, and template organization but nothing changes
Hi thanks for that. I still an issue, button on the right side to select date in the template is not working. I click on it but nothing..
this is the code modified:
in setting.py
# needed for using bootstrap_datepicker_plus
BOOTSTRAP3 = {
'include_jquery': True,
}
and add 'bootstrap_datepicker_plus', in installed apps
html file:
{% extends 'imports/base.html' %}
{% load bootstrap3 %}
<!-- necessaire pour date picker -->
{% block extra_css %}
{{ form.media.css }}
{% endblock %}
{% block extra_js %}
{{ form.media.js }}
{% endblock %}
<!-- Fin date picker -->
{% block title %}Imports Company{% endblock %}
{% block heading %}<h3 class="page-header-center">Creation Company</h3> {% endblock %}
<hr>
<hr>
{% block page %}
<form method="POST">
{% csrf_token %}
<div class="col-lg-4 col-md-4 col-sm-4 content">
{% bootstrap_form company_form %}
<button type="submit" class="btn btn-pink pull-right">Create</button>
</div>
</form>
{% endblock %}
imports/base.html:
{% load staticfiles %}
{% load bootstrap3 %} {# import bootstrap4/bootstrap3 #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- Necessaire pour bootstrap datepicker -->
{% bootstrap_css %} {# Embed Bootstrap CSS #}
{% block extra_css %}
{{ form.media.css }}
{% endblock %}
<!-- fin du code boots trap datepicker -->
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-lg-2 col-md-2 col-sm-2 sidebar">
{% block sidebar %}{% endblock %}
</div>
<div class="col-lg-10 col-lg-offset-2 col-md-10 col-md-offset-2 col-sm-10 col-sm-offset-2 content">
{% block heading %}{% endblock %}
{% block page %}{% endblock %}
</div>
</div>
</div>
<!-- Necessaire pour bootstrap datepicker -->
{% bootstrap_javascript jquery='full' %} {# Embed Bootstrap JS+jQuery #}
{% block extra_js %}
{{ form.media.js }}
{% endblock %}
<!-- fin du code boots trap datepicker -->
</body>
</html>
and
forms.py:
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = ("company_name", "fiscal_end_of_year")
widgets = {
'fiscal_end_of_year': DatePickerInput(), # default date-format %m/%d/%Y will be used
}
models.py:
class Company(models.Model):
company_id = models.IntegerField(default=170)
company_name = models.CharField(max_length=100, null=False)
fiscal_end_of_year = models.DateField()
I missed something but where :-) ?
Expects to see calendar when clicking on the button

Jinja2 Multi-level template inheritance issue

I have the following three files in a Django App, with the template engine being Jinja2
skeleton.html
<head>
{% block head_content %}
<meta charset="utf-8">
<title> {% if page_title %} {{ page_title }} | {% endif %} Bhargavi Books & Stationery </title>
<link rel="stylesheet" href="{{ static("css/semantic.min.css") }}">
<link rel="stylesheet" href="{{ static("Icons/font-awesome.min.css") }}">
{% endblock head_content %}
</head>
<body>
<div id="navigation">
{% block navigation %}
<div class="ui three item menu">
<a class="active item">Home</a>
<a class="item">New Bill</a>
<a class="item">View Bills</a>
</div>
{% endblock navigation %}
</div>
<div id="frame">
{% block frame_content %}
<p> Body content goes here. Body for {{ content_name }}</p>
{% endblock frame_content %}
</div>
<div id="app">
{% block app_content %}
<p> APP content goes here. Body for {{ content_name }}</p>
{% endblock app_content %}
</div>
{% block scripts %}
<script src="{{ static("js/jquery.js") }}"></script>
<script src=" {{ static("js/semantic.min.js") }} "></script>
{% endblock scripts %}
</body>
base.html
{% extends "skeleton.html" %}
{% from "macros/globalmacros.html" import
SUIIconList,SUISimpleList,
SUIImageLabel,SUILabel,
SUIActionInput,SUILabeledInput,SUIInput,
SUIDimmableActionCard,SUICard,
%}
{% block frame_content %}
Frame Content
{% endblock frame_content %}
{% block scripts %}
{{ super() }}
<script src=" {{ static("js/globalmacros.js") }} "></script>
{% endblock scripts %}
dashboard.html
{% extends "base.html" %}
<div>
{% block body_content %}
Body 3
{% endblock body_content %}
</div>
<div>
{% block app_content %}
DASHBOARD
{% endblock app_content %}
</div>
In this setup, Jinja renders everything except the "DASHBOARD" in the final page. However, when I add an empty block in "base.html", like so..
{% block app_content %}
App content Goes here...
{% endblock app_content %}
In the final template, "DASHBOARD" is printed. Is this some quirk in Jinja? Is this behavior defined in any docs??
I understand your issue: you've got template A, template B (extends template A), and template C (extends template B). There's a block defined in template A, but it's not showing up in the page that uses template C, unless you define that block in template B. If you do that, then the block in question shows up.
First: you are correct in your understanding that this is not how the Jinja template hierarchy is supposed to work. Second, I did not encounter your issue (found a different one, though), and I have constructed a proof to demonstrate this. Here's what I did (again, using Python 3 and Django 1.11):
$ python startproject myapp
In the myapp/myapp/settings.py file, I updated the template engine:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [
os.path.join(BASE_DIR, 'myapp/templates') # hack / should add `myapp` to INSTALLED_APPS instead
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
In myapp/myapp/urls.py, I created a dummy view function & route:
from django.conf.urls import url
from django.shortcuts import render_to_response
def home(request):
return render_to_response('dashboard.html')
urlpatterns = [
url(r'^$', home),
]
And finally, I established those templates, but I removed the call to import your macros, along with all instances of static().
Here is the myapp/myapp/templates/skeleton.html file:
<!doctype html>
<html lang="en">
<head>
{% block head_content %}
<meta charset="utf-8">
<title> {% if page_title %} {{ page_title }} | {% endif %} Bhargavi Books & Stationery </title>
{% endblock head_content %}
</head>
<body>
<div id="navigation">
{% block navigation %}
<div class="ui three item menu">
<a class="active item">Home</a>
<a class="item">New Bill</a>
<a class="item">View Bills</a>
</div>
{% endblock navigation %}
</div>
<div id="frame">
{% block frame_content %}
<p> Body content goes here. Body for {{ content_name }}</p>
{% endblock frame_content %}
</div>
<div id="app">
{% block app_content %}
<p> APP content goes here. Body for {{ content_name }}</p>
{% endblock app_content %}
</div>
{% block scripts %}
{% endblock scripts %}
</body>
</html>
Here is the myapp/myapp/base.html file:
{% extends "skeleton.html" %}
{% block frame_content %}
Frame Content
{% endblock frame_content %}
{% block scripts %}
{{ super() }}
{% endblock scripts %}
And here is the myapp/myapp/templates/dashboard.html file:
{% extends "base.html" %}
<div>
{% block body_content %}
Body 3
{% endblock body_content %}
</div>
<div>
{% block app_content %}
DASHBOARD
{% endblock app_content %}
</div>
And here is the output, after viewing that page in my browser:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Bhargavi Books & Stationery </title>
</head>
<body>
<div id="navigation">
<div class="ui three item menu">
<a class="active item">Home</a>
<a class="item">New Bill</a>
<a class="item">View Bills</a>
</div>
</div>
<div id="frame">
Frame Content
</div>
<div id="app">
DASHBOARD
</div>
</body>
</html>
Since this all works as expected*, my conclusion is that you might have a problem with the base.html template file. Perhaps it's failing to import your macros, and subsequently not behaving correctly? I notice a trailing comma in there, and I'm not sure if that could be problematic or not. I would suggest using the above code as a starting point, and then slowly add back in the parts that I stripped out, and perhaps the problem will become visible/understandable.
*One thing I found odd, that I don't understand: the body_content block is completely missing from my output, unless I define that block in the skeleton.html template. It doesn't work if I define it in the base.html template, which seems wrong to me, because then we're not really extending that second template (base.html)... so there does seem to be something weird there... but I was not able to encounter the original issue you described, so maybe this will be helpful in that particular regards, at least.

How to set up a custom template in djangocms

I've successfully installed djangocms on a Ubuntu machine, and now I would like to integrate a custom template bought from Envato.
After I have installed it, djangocms came with its own simple template files which are located in mysite/templates:
base.html
{% load cms_tags staticfiles sekizai_tags menu_tags %}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}This is my new project home page{% endblock title %}</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap-theme.min.css">
{% render_block "css" %}
</head>
<body>
{% cms_toolbar %}
<div class="container">
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Project name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
{% show_menu 0 1 100 100 "menu.html" %}
</ul>
</div>
</div>
{% block content %}{% endblock content %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/js/bootstrap.min.js"></script>
{% render_block "js" %}
</body>
</html>
feature.html
{% extends "base.html" %}
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
<div class="jumbotron">
{% placeholder "feature" %}
</div>
<div>
{% placeholder "content" %}
</div>
{% endblock content %}
menu.html
{% load i18n menu_tags cache %}
{% for child in children %}
<li class="{% if child.ancestor %}ancestor{% endif %}
{% if child.selected %} active{% endif %}
{% if child.children %} dropdown{% endif %}">
{% if child.children %}
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
{{ child.get_menu_title }} <span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
</ul>
{% else %}
<span>{{ child.get_menu_title }}</span>
{% endif %}
</li>
{% if class and forloop.last and not forloop.parentloop %}{% endif %}
{% endfor %}
page.html
{% extends "base.html" %}
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
{% placeholder "content" %}
{% endblock content %}
I have read their documentation but I haven't found anything related to some custom template integration. Could anyone please lead me in the right direction ?
EDIT1:
I have added in CMS_TEMPLATES:
CMS_TEMPLATES = (
## Customize this
('page.html', 'Page'),
('feature.html', 'Page with Feature'),
('index.html', 'oriel.io') # this is what I added
)
but nothing happened.
Add your templates to CMS_TEMPLATES in your settings file.
I recently met the same problem! So let me try to explain
1) You should extend PageAdmin in admin.py
In admin side, when you want to choose template for page ('advanced settings') it will call AdvancedSettingsForm by default. but we must to extend too to give your templates.
class ExtendedPageAdmin(PageAdmin):
def get_form_class(self, request, obj=None, **kwargs):
if 'advanced' in request.path_info:
return ExtendedAdvancedSettingsForm
elif 'permission' in request.path_info:
return PagePermissionForm
elif 'dates' in request.path_info:
return PublicationDatesForm
return self.form
and DO NOT forget unregister and register
admin.site.unregister(Page)
admin.site.register(Page, ExtendedPageAdmin)
2) OK) You have choosen ('advanced settings') and there must be choice among your custom templates.
class ExtendedAdvancedSettingsForm(AdvancedSettingsForm):
def __init__(self, *args, **kwargs):
super(ExtendedAdvancedSettingsForm, self).__init__(*args, **kwargs)
template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
self.fields['template'] = forms.ChoiceField(choices=template_choices)
3) Ok, wee see custom templates for page, but there will be error if you want to save it. It's because of Page model. It looks like this:
#python_2_unicode_compatible
class Page(six.with_metaclass(PageMetaClass, MP_Node)):
"""
A simple hierarchical page model
"""
...
template_choices = [(x, _(y)) for x, y in get_cms_setting('TEMPLATES')]
...
template = models.CharField(_("template"), max_length=100,
choices=template_choices, default=TEMPLATE_DEFAULT
help_text=_('The template used to render the content.'))
4) So you should change template_choice during init the Page object. Let's use signals
def after_page_init(sender, instance, **kwargs):
instance._meta.get_field_by_name('template')[0]._choices = []
def patch_cms_page():
from cms.models import Page
from django.db.models.signals import post_init
post_init.connect(after_page_init, sender=Page)
and finally call patch_cms_page() in urls.py )