Django apps that add content to the same page - python

I have written a Django website with a simple home page containing a list of the following menu items:
Home
Users
Contact
I am now working on an optional Django app for this website. When installed, I would like it to add an extra menu item to the home page called "Extras".
What is the best way to achieve this sort of thing in Django?
I have considered adding something like this to my settings.py file:
MENU_ITEMS = [
'Home',
'Users',
'Contact',
]
Then inside my app's __init__.py, I would do something like this:
from django.conf import settings
settings.MENU_ITEMS.append('Extras')
And the views.py file would then pass this MENU_ITEMS list to the home page template. Is this the correct approach or is there a better way?

A tip i would give you from experience: don't mess with settings in runtime if possible, those variables are global and changing them may cause some nasty bugs. I'm not sure but with that code you may end up with something like:
MENU_ITEMS = [
'Home',
'Users',
'Contact',
'Extras',
'Extras',
'Extras',
'Extras',
]
Again, I'm not sure of that but you don't need to mess with your settings to achieve your purpose.
A way more clean approach is let your view manage your view. If all you want is a menu, create a base template and put the menu there and then extend from it. If you want to add anything in the future you will need to change that piece only (You can add conditions there if you want to render some parts depending on user or something).
For more details refer to the django docs.
For example:
<div class="header navbar">
<div class="container">
<a class="navbar-brand" href="/">{% endraw %}{{ cookiecutter.project_name }}{% raw %}</a>
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
{% if request.user.is_authenticated %}
<li>{% trans "My Profile" %}</li>
<li>{% trans "Logout" %}</li>
{% else %}
<li>{% trans "Sign Up" %}</li>
<li>{% trans "Log In" %}</li>
{% endif %}
</ul>
</div>
</div>
{% block content %}
{% endblock content %}
If this is defined in your base template, the pages that extend it will show it by default, overriding only the section where the block content is located. If you want to add another link to your navbar just do something like:
<li class="active">My new item</li>
You define 'my_other_url' as usual in your urls.py.
This is the right approach to do what i think you are trying to do. You let the templates handle how your site looks, don't mess views (as in mvc) with your controller.
If you want to make the extra item optional you just have to send a flag or something to the template and use:
{% if flag %}
<li class="active">My new item</li>
{% endif %}

Related

How do i show an active link in a django navigation bar dropdown list?

I have a navbar menu with a list of links which i want to show the active link when the user is on the page, so far i have managed to do this with links that dont have dropdowns like this.
But I cannot seem to get it right with the dropdown links in such a way that if the user is on a page on the dropdown link the parent link on the navbar gets highlighted.like shown below
Any help would be greatly appreciated.
If you define your URLs with names like this:
url('', 'home_view', name='home'),
url('posts/', 'posts_view', name='blog'),
url('contact/', 'contact_view', name='contact'),
You can use these names in the template to make the if statements work:
{% with request.resolver_match.url_name as url_name %}
<ul id="menu">
<li class="{% if url_name == 'home' %}active{% endif %}">Home</li>
<li class="{% if url_name == 'blog' %}active{% endif %}">Posts</li>
<li class="{% if url_name == 'contact' %}active{% endif %}">Contact</li>
</ul>
{% endwith %}
This saves you from problems with duplication in url paths.
You can do this by passing a variable in context dictionary views.
Example:
context['faculties']=True
and then in html
{% if faculties %}active{% endif %}
For every view function you can set a variable to which you want to make active.
There are two ways: either manage your CSS to highlight the parent item if any of its children are "active" or (at the expense of some maintenance overhead and loss of DRY) test for membership in the template:
<li class="dropdown {% if url_name in "neo_app:business,neo_app:IT,neo_app:hospitality" %}
active
{% endif %}>Faculties</li>
You can do this all on the front end very easily without passing anything from the backend based on the URL.
If your url for example is "/faculties", you can do:
{% if '/faculties' in url %} active {% endif %}

Statik: Implement navigation from data/views

I have a website build via Statik (a static web site generator, build with python).
Now I'd like to build a navigation out from my existing data or views, via a property like e.g. show_in_navigation = Boolean.
I thought about writing a custom template tag to get a list of all instances with show_in_navigation = True - but I don't know where to start or what would be the best approach in the first place;-)
My goal is a Twitter Bootstrap navbar-nav component filled with my show_in_navigation entries (with a bonus for highlighting the current page).
Any hints or tips?
My current implementation defines a navigation_bar variable in the main configuration:
# config.yml
context:
static:
navigation_bar: [['home', 'Home'], ['about', 'About'], ['contact', 'Contact']]
# templates/includes/navigation.html
<ul>
{% for pk, title in navigation_bar %}
<li {% if pk == active_page %} class="active"{% endif %}>
{{ title }}
</li>
{% endfor %}
</ul>
# templates/about.html
{% extends "base.html" %}
{% set active_page = "about" %}
... but that seems to be very verbose and not dry (e.g. repeating site titles, setting the active page)...

Django. Customize action for model

I need to edit the "Add Object" action in the admin. It needs to redirect the user to a custom cause the logic required for adding objects is too complex to be managed in the admin. So, how do I make this possible? i.e:
The picture shows a django-suit admin, but the question is the same. How can I make that button redirect to a custom url? Or, how can I create a similar button that redirects to a custom url (I could disable the default create and leave only the custom button).
Override change_list_template html, the block object-tools-items. It's where add button is placed.
class MyModelAdmin(admin.ModelAdmin):
change_list_template = 'change_list.html'
In your change_list.html
{% extends "admin/change_list.html" %}
{% load i18n admin_static admin_list %}
{% block object-tools-items %}
{% if has_add_permission %}
<li>
<a href="your/custom/url" class="addlink">
{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}
</a>
</li>
{% endif %}
{% endblock %}
You need to add your new html in any dir that is included on TEMPLATE_DIRS options. But, you should do it inside your model's app.
-app
-templates
-admin
change_list.html
Add above dir in TEMPLATE DIRS paths.

Django - Include app template in base template

I trying to include app result in base template. Template is displayed properly but I don't see any results. When I open app url directly (127.0.0.1/Project/config/) it show results.
Project / urls.py
urlpatterns = patterns('',
url(r'^$', 'Project.views.index'),
url(r'^config/', DisplayChangelog),
)
config / views.py
from config.models import Changelog
def DisplayChangelog(request):
changes = Changelog.objects.all()
t = loader.get_template("changelog.html")
c = Context({'changes': changes})
return HttpResponse(t.render(c))
templates / base.html
...
<ul class="nav navbar-nav">
{% include "changelog.html" %}
</ul>
...
templates / changelog.html
...
{% for change in changes %}
<li class="media">
<div class="body">
{{ change.desc }}
<div class="date">{{ change.date }}</div>
</div>
</li>
{% endfor %}
...
First of all you have to put some variables in your base.html if you use them on every single page, but also you have to pass these variables somehow. Of course you won't add one more object to the context in each view so there is an idea of context processors. Take a look at the docs if this is really what you need.
In your case, I think it's just enough to add a changes variable to the index view's context and include your changelog in the template rendered by index view.
So basically I want to say that you have to pass objects to the view's context if you want to use them in your templates, even if you use them in included templates.
You can try this after you define "changes" variable in your view:
{% include "changelog.html" with changes=changes %}

Navigation in Django, using url.patterns

I learn Python, doing test project.
Case: I need to use class="active" for <li> based on page url. Now I use django.core.context_processors.request to take url from path.
How it looks now:
<li role="presentation" {% if request.path == '/' %}class="active"{% endif %}>Home</li>
<li role="presentation" {% if '/groups' in request.path %}class="active"{% endif %}>Groups</li>
So, if I open main page - first <li> is active, if url contains "/groups" - secon <li> is active. And it works, but I want to do it more complex, comparing url with url.patterns in urls.py:
url(r'^$', 'students.views.students_list', name='home'),
url(r'^groups/$', 'students.views.groups_list', name='groups')
Question: how to do it? I can't just use {% url 'groups' %} in if-statement because of syntax error. Need some advice.
You can assign the result of url tag to the variable.
{% url 'groups' as groups_url %}
# use groups_url variable somewhere

Categories

Resources