How to use different template for different browser - django

I'd like to deliver special versions of my django site for different (mobile-)browser.
What are possible solutions to do this?

In your view, do smthg like this
def map(request, options=None, longitude=None, latitude = None):
if 'iPhone' in request.META["HTTP_USER_AGENT"]:
user_agent = 'iPhone'
elif 'MSIE' in request.META["HTTP_USER_AGENT"]:
user_agent ='MSIE'
else: user_agent=''
print user_agent
return render_to_response('map/map.html',
{
'user_agent': user_agent
})
and in your template
{% ifnotequal user_agent "iPhone" %}
{% ifequal user_agent "MSIE" %}
{% include 'map/map_ie.html' %}
{% else %}
{% include 'map/map_default.html' %}
{% endifequal %}
{% else %}
{% include 'map/map_iphone.html' %}
{% endifnotequal %}

best practice: use minidetector to add the extra info to the request, then use django's built in request context to pass it to your templates like so.
from django.shortcuts import render_to_response
from django.template import RequestContext
def my_view_on_mobile_and_desktop(request)
.....
render_to_response('regular_template.html',
{'my vars to template':vars},
context_instance=RequestContext(request))
then in your template you are able to introduce stuff like:
<html>
<head>
{% block head %}
<title>blah</title>
{% if request.mobile %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-mobile.css">
{% else %}
<link rel="stylesheet" href="{{ MEDIA_URL }}/styles/base-desktop.css">
{% endif %}
</head>
<body>
<div id="navigation">
{% include "_navigation.html" %}
</div>
{% if not request.mobile %}
<div id="sidebar">
<p> sidebar content not fit for mobile </p>
</div>
{% endif %>
<div id="content">
<article>
{% if not request.mobile %}
<aside>
<p> aside content </p>
</aside>
{% endif %}
<p> article content </p>
</aricle>
</div>
</body>
</html>

Related

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.

Django template extending

I am new with Django and trying to understand how to use templates and I have an issue with template extending. I have 3 templates. the first one in the base.html
{% load staticfiles%}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" type="text/css" href="{%static 'css/main.css'%}">
<title>Home</title>
</head>
<body >
<div class="page-header">
<h1>Django Project</h1>
</div>
<div class="content container">
<div class="row">
<div class="col-sm-8">
{%block content %}
{%endblock%}
</div>
<div class="col-sm-4">
{%block lastposts %}
{%endblock%}
</div>
</div>
</div>
</body>
</html>
Second one is post_list.html (which I render from views)
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
and latest_posts.html
{% extends 'blog/base.html' %}
{% block lastposts %}
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}
{% endblock %}
The problem is that the content of latest_posts.html does not show up. I know that something is wrong. In that case how I can use extending in django to to separate my code in these 3 files. Thanks.
*UPDATE
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
# Create your views here.
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
If you want to display the contents of latest_posts.html in post_list.html, you'll have to include it
post_list.html
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
{%block lastposts %}
{% include 'blog/latest_posts.html' %}
{% endblock %}
latest_posts.html (only remove the extend and block tags)
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}

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 )

Django http404 error urlconf confusion

I was really confused why I was receiving Http404 error. To be more clear heres my code:
My app named books
views.py
from django.shortcuts import render_to_response
from django.http import Http404
from django.template import RequestContext
from books.models import *
def index(request):
title = 'Book Gallery'
books = Book.objects.all().order_by('-id')
lang_list = Lang.objects.all().order_by('-lang')
template = 'books/index.djhtml'
context = {'books': books, 'title': title, 'lang_list': lang_list}
return render_to_response( template, context, context_instance=RequestContext(request) )
def by_book_slug(request, bookslug):
slug = bookslug
try:
book = Book.objects.get(slug=slug)
except:
raise Http404
title = book.name
template = 'books/singlebook.djhtml'
context = {'book': book, 'title': title}
return render_to_response( template, context, context_instance=RequestContext(request) )
def by_lang_slug(request, langslug):
filter = langslug
try:
language = Lang.objects.get(slug=filter)
except:
raise Http404
lang_list = Lang.objects.all().order_by('-lang')
books = Book.objects.filter(lang=language).order_by('-id')
title = language
template = 'books/by_language.djhtml'
context = {'books': books, 'title': title, 'filter': filter, 'lang_list': lang_list}
return render_to_response( template, context, context_instance=RequestContext(request) )
urls.py inside my book app folder
from django.conf.urls import patterns, include, url
from books import views
urlpatterns = patterns('',
url(r'(?P<langslug>.*)/$', views.by_lang_slug, name='by_lang'),
url(r'(?P<bookslug>.*)/$', views.by_book_slug, name='by_book'),
url(r'^$', views.index, name='book_gallery'),
)
link that pertains to langslug url conf works but those links for bookslug url conf does not work. When I try to switch them down and up, one of them work and the other one is not.
I really don't know what is happening here. Any help will be a great help. Thanks.
the index template of my books app
{% extends 'base.djhtml' %}
{% block title %} | Gallery{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/style.css" />
{% endblock %}
{% block content_header %}
{% endblock %}
{% block content_body %}
<div class="row">
<div class="span3">
<strong>filtered by >
{% if filter %}
{{ filter }}
{% else %}
All
{% endif %}
</strong>
<ul class="nav nav-list">
<li class="nav-header">Filter</li>
<li class="nav-header
{% if not filter %}
active
{% endif %}
">All</li>
{% for list in lang_list %}
<li class="nav-header
{% if filter == list.slug %}
active
{% endif %}
">
{{ list.lang }}
</li>
{% endfor %}
</ul>
</div>
<div class="span9">
{% for book in books %}
<div class="span3">
<a href="{{ book.book_cover.url }}">
<img alt="{{book.name}}" src="{{ book.thumbnail.url }}" />
</a>
<h4>{{book.name}}</h4>
<p>{{book.desc|truncatewords:15}}</p>
View more...
</div>
{% endfor %}
</div>
</div>
{% endblock %}
The by_language template for my book app
{% extends 'base.djhtml' %}
{% block title %} | Gallery{% endblock %}
{% block stylesheets %}
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/style.css" />
{% endblock %}
{% block content_header %}
{% endblock %}
{% block content_body %}
<div class="row">
<div class="span3">
<strong>filtered by >
{% if filter %}
{{ filter }}
{% else %}
All
{% endif %}
</strong>
<ul class="nav nav-list">
<li class="nav-header">Filter</li>
<li class="nav-header
{% if not filter %}
active
{% endif %}
">All</li>
{% for list in lang_list %}
<li class="nav-header
{% if filter == list.slug %}
active
{% endif %}
">
{{ list.lang }}
</li>
{% endfor %}
</ul>
</div>
<div class="span9">
{% for book in books %}
<div class="span3">
<a href="{{ book.book_cover.url }}">
<img alt="{{book.name}}" src="{{ book.thumbnail.url }}" />
</a>
<h4>{{book.name}}</h4>
<p>{{book.desc|truncatewords:15}}</p>
View more...
</div>
{% endfor %}
</div>
</div>
{% endblock %}
I have included a raise Http404 method when specified slug does not match to any query in the database. The thing I was confused about is, when I try to switch langslug and bookslug urlconf, links that are associated to one of these url works and the other is not.
Based on your url, if I put value on it even though they have different view, the result would be:
urlpatterns = patterns('',
# http://localhost:8000/English/
url(r'(?P<langslug>.*)/$', views.by_lang_slug, name='by_lang'),
# http://localhost:8000/YourBook/
url(r'(?P<bookslug>.*)/$', views.by_book_slug, name='by_book'),
# http://localhost:8000/
url(r'^$', views.index, name='book_gallery'),
)
Have you notice it, they have the same pattern so the first view execute is the by_lang_slug. So if you change the order the other one will be executed first. The best thing to do about it is to have a unique url name.
urlpatterns = patterns('',
# http://localhost:8000/lang/English/
url(r'lang/(?P<langslug>.*)/$', views.by_lang_slug, name='by_lang'),
# http://localhost:8000/book/YourBook/
url(r'book/(?P<bookslug>.*)/$', views.by_book_slug, name='by_book'),
# http://localhost:8000/
url(r'^$', views.index, name='book_gallery'),
)
Now they are different....

Get length of an item passed in request (and context) (django-breadcrumbs)

I am using this django-plugin here: https://github.com/chronossc/django-breadcrumbs
But I can't seem to be able to check in the templates if there is actually an array of breadcrumbs or not… I have tried:
{%if request.breadcrumbs%} {% if request.breadcrumbs|length > 0%}
and so on… but nothing truly tells me if there are some or not.
I want this bar to appear if I passed in breadcrumbs, and not appear in the case that I didn't pass some breadcrumbs in my view:
{% if request.breadcrumbs|length > 0 %}
<div class="navbar navbar-fixed-top" style="top:38px;z-index:1029;" id="breadcrumb-sticky-header">
<div class="container">
<div class="container-fluid">
<div class="row-fluid">
<ul id="breadcrumb-sticky-header-inner" class="breadcrumb">
{% for breadcrumb in request.breadcrumbs %}
{% if not forloop.last %}
<li>{{ breadcrumb.name }} <span class="divider">/</span></li>
{% else %}
<li class="active">{{ breadcrumb.name }}</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endif %}
Here is the code in my view:
#login_required
def view(request, t_id):
try:
tshoot = Troubleshoot.objects.select_related('category', 'equipment', 'equipment__model').get(pk=t_id)
request.breadcrumbs([
(("%s: %s" % (tshoot.equipment.model.name, tshoot.equipment.serial)),
'/equipment/view/%s/' % (tshoot.equipment.id)),
(("%s" % (tshoot.category.name)),
'/troubleshoot/categories/view/%s/' % (tshoot.category.id)),
((tshoot.title), '')
])
Based on the code in the django-breadcrumbs project (line 191 in breadcrumbs.py: https://github.com/chronossc/django-breadcrumbs/blob/master/breadcrumbs/breadcrumbs.py#L191), It looks like they've implemented a .all() method.
You should be able to use the |length template filter on the results of the .all() method to get the result you want, like so:
{% if request.breadcrumbs and request.breadcrumbs.all|length > 0 %}
I have not tested this; this is what my quick code inspection revealed.
Not sure what request.breadcrumbs|length > 0 does, but I would use the sample template:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Breadcrumbs test page | {% for b in request.breadcrumbs %}{{ b.name }}{% if not forloop.last %} > {% endif %}{% endfor %}</title>
</head>
<body>
{{ request.breadcrumbs }}
<p>Breadcrumb: {% for b in request.breadcrumbs %}{{ b.name }}{% if not forloop.last %} / {% endif %}{% endfor %}</p>
<p>Links: <a href='/'>Home</a> | <a href='/someview/'>Breadcrumb in view</a> | <a href='/flat01/'>Flatpages</a>
<p>Content: <br>
{% if text %}{{ text }}{% endif %}
{% if flatpage %}{{ flatpage.content }}{% endif %}
</body>
</html>
and view until you are comfortable with how it works:
# Create your views here.
from django.shortcuts import render_to_response
from django.template.context import RequestContext
def home(request):
print request.breadcrumbs
return render_to_response('home.html',
{'text': 'Hello, this is home!'},
context_instance=RequestContext(request))
def someview(request):
request.breadcrumbs('just a view to show some url', request.path)
return render_to_response('home.html',
{'text': 'Hello, this is some second view'},
context_instance=RequestContext(request))
(from: https://github.com/chronossc/django-breadcrumbs/blob/master/breadcrumbs_sample)