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

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)

Related

Django admin template - grid instead of list

What is the easiest / fastest way to override Django admin form to display grid of elements instead of list? My model includes a field for a 100x100px pic, and it would be easier to see them as a grid of pictures, not a list.
This is not terribly difficult, but it requires you to copy several large chunks of code from the Django library and incorporate them into your own application. Here's the overview:
You'll need to copy and then modify several template tags from django.contrib.admin.templatetags.admin_list:
django.contrib.admin.templatetags.admin_list.items_for_result
django.contrib.admin.templatetags.admin_list.result_list
django.contrib.admin.templatetags.admin_list.results
django.contrib.admin.templatetags.admin_list.result_list_tag
You'll need to copy and then modify a couple of templates:
django/contrib/admin/templates/admin/change_list.html
django/contrib/admin/templates/admin/change_list_results.html
For purposes of illustrating the solution, I have created an app called spam and a model called SpamPhoto, along with a model admin that is customized to display the image tag. I am using Bootstrap 4 for the grid. There are still some issues you might need to track down and figure out, like getting rid of the checkbox that shows up for each item. But this code should get about 90% of the way there.
Here's an overview of the files that I created/modified, and which you'll find below:
spam/models.py: contains the SpamPhoto model
spam/admin.py: contains the SpamPhotoAdmin
spam/templatetags/spamphoto_admin_list.py: contains the template tag / functions that will render the customized change list
spam/templates/admin/spam/spamphoto/change_list.html: this is the main changelist template, and only has a few small changes: it loads our custom template tags, it includes Bootstrap CSS, and it calls a customized template tag (defined below)
spam/templates/admin/spam/spamphoto/change_list_results.html: heavy modifications here, getting rid of the table elements and replacing with divs.
So again, this is a LOT of code, and most of it is lifted directly without very many changes. Here we go:
# spam/models.py
from django.db import models
class SpamPhoto(models.Model):
name = models.CharField(max_length=100)
image = models.ImageField()
# spam/admin.py
from django.contrib import admin
from django.utils.html import mark_safe
class SpamPhotoAdmin(admin.ModelAdmin):
list_display = ('name', 'image_tag')
list_display_links = ('name', 'image_tag')
def image_tag(self, obj):
return mark_safe(f'<img class="img-fluid" src="{obj.image.url}" />')
# spam/templatetags/spamphoto_admin_list.py
from django import template
# Note: you should import these from their "correct" locations! This is cheap/dirty:
from django.contrib.admin.templatetags.admin_list import (ResultList, result_headers, result_hidden_fields,
_coerce_field_name, lookup_field, ObjectDoesNotExist,
display_for_field, datetime, display_for_value, models,
mark_safe, NoReverseMatch, add_preserved_filters, format_html)
from django.contrib.admin.templatetags.base import InclusionAdminNode
register = template.Library()
def spamphoto_items_for_result(cl, result, form):
"""
Cloned from django.contrib.admin.templatetags.admin_list.items_for_result
The only modification is found at the very end of this function, where the HTML
tags are changed from `td` to `div`
"""
def link_in_col(is_first, field_name, cl):
if cl.list_display_links is None:
return False
if is_first and not cl.list_display_links:
return True
return field_name in cl.list_display_links
first = True
pk = cl.lookup_opts.pk.attname
for field_index, field_name in enumerate(cl.list_display):
empty_value_display = cl.model_admin.get_empty_value_display()
row_classes = ['field-%s' % _coerce_field_name(field_name, field_index)]
try:
f, attr, value = lookup_field(field_name, result, cl.model_admin)
except ObjectDoesNotExist:
result_repr = empty_value_display
else:
empty_value_display = getattr(attr, 'empty_value_display', empty_value_display)
if f is None or f.auto_created:
if field_name == 'action_checkbox':
row_classes = ['action-checkbox']
boolean = getattr(attr, 'boolean', False)
result_repr = display_for_value(value, empty_value_display, boolean)
if isinstance(value, (datetime.date, datetime.time)):
row_classes.append('nowrap')
else:
if isinstance(f.remote_field, models.ManyToOneRel):
field_val = getattr(result, f.name)
if field_val is None:
result_repr = empty_value_display
else:
result_repr = field_val
else:
result_repr = display_for_field(value, f, empty_value_display)
if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
row_classes.append('nowrap')
row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
# If list_display_links not defined, add the link tag to the first field
if link_in_col(first, field_name, cl):
table_tag = 'th' if first else 'td'
first = False
# Display link to the result's change_view if the url exists, else
# display just the result's representation.
try:
url = cl.url_for_result(result)
except NoReverseMatch:
link_or_text = result_repr
else:
url = add_preserved_filters({'preserved_filters': cl.preserved_filters, 'opts': cl.opts}, url)
# Convert the pk to something that can be used in Javascript.
# Problem cases are non-ASCII strings.
if cl.to_field:
attr = str(cl.to_field)
else:
attr = pk
value = result.serializable_value(attr)
link_or_text = format_html(
'<a href="{}"{}>{}</a>',
url,
format_html(
' data-popup-opener="{}"', value
) if cl.is_popup else '',
result_repr)
yield format_html('<{}{}>{}</{}>', table_tag, row_class, link_or_text, table_tag)
else:
# By default the fields come from ModelAdmin.list_editable, but if we pull
# the fields out of the form instead of list_editable custom admins
# can provide fields on a per request basis
if (form and field_name in form.fields and not (
field_name == cl.model._meta.pk.name and
form[cl.model._meta.pk.name].is_hidden)):
bf = form[field_name]
result_repr = mark_safe(str(bf.errors) + str(bf))
# THIS LINE HAS BEEN CHANGED:
yield format_html('<div{}>{}</div>', row_class, result_repr)
if form and not form[cl.model._meta.pk.name].is_hidden:
# THIS LINE HAS BEEN CHANGED:
yield format_html('<div>{}</div>', form[cl.model._meta.pk.name])
def spamphoto_result_list(cl):
"""
Cloned from django.contrib.admin.templatetags.admin_list.result_list
The only change is to the `results` value in the returned dict, where we call `spamphoto_results`
"""
headers = list(result_headers(cl))
num_sorted_fields = 0
for h in headers:
if h['sortable'] and h['sorted']:
num_sorted_fields += 1
return {
'cl': cl,
'result_hidden_fields': list(result_hidden_fields(cl)),
'result_headers': headers,
'num_sorted_fields': num_sorted_fields,
# THIS LINE HAS BEEN CHANGED:
'results': list(spamphoto_results(cl)),
}
def spamphoto_results(cl):
"""
Cloned from django.contrib.admin.templatetags.admin_list.results
The only changes are where we call `spamphoto_items_for_result` instead of `items_for_result`
"""
if cl.formset:
for res, form in zip(cl.result_list, cl.formset.forms):
# THIS LINE HAS BEEN CHANGED:
yield ResultList(form, spamphoto_items_for_result(cl, res, form))
else:
for res in cl.result_list:
# THIS LINE HAS BEEN CHANGED:
yield ResultList(None, spamphoto_items_for_result(cl, res, None))
#register.tag(name='spamphoto_result_list')
def spamphoto_result_list_tag(parser, token):
"""
Cloned from django.contrib.admin.templatetags.admin_list.result_list_tag
The only change is to the `func` param, which now uses out custom `spamphoto_result_list` function
"""
return InclusionAdminNode(
parser, token,
# THIS LINE HAS BEEN CHANGED:
func=spamphoto_result_list,
template_name='change_list_results.html',
takes_context=False,
)
# spam/templates/admin/spam/spamphoto/change_list.html
{% extends "admin/base_site.html" %}
{% load i18n admin_urls static admin_list %}
<!-- ADDED THIS LINE / INCLUDING OUR CUSTOM TEMPLATE TAGS -->
{% load spamphoto_admin_list %}
{% block extrastyle %}
{{ block.super }}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/changelists.css" %}">
{% if cl.formset %}
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">
{% endif %}
{% if cl.formset or action_form %}
<script src="{% url 'admin:jsi18n' %}"></script>
{% endif %}
{{ media.css }}
{% if not actions_on_top and not actions_on_bottom %}
<style>
#changelist table thead th:first-child {width: inherit}
</style>
{% endif %}
<!-- ADDED THIS LINE / INCLUDING BOOTSTRAP -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css">
{% endblock %}
{% block extrahead %}
{{ block.super }}
{{ media.js }}
{% endblock %}
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %}
{% if not is_popup %}
{% block breadcrumbs %}
<div class="breadcrumbs">
{% translate 'Home' %}
› {{ cl.opts.app_config.verbose_name }}
› {{ cl.opts.verbose_name_plural|capfirst }}
</div>
{% endblock %}
{% endif %}
{% block coltype %}{% endblock %}
{% block content %}
<div id="content-main">
{% block object-tools %}
<ul class="object-tools">
{% block object-tools-items %}
{% change_list_object_tools %}
{% endblock %}
</ul>
{% endblock %}
{% if cl.formset and cl.formset.errors %}
<p class="errornote">
{% if cl.formset.total_error_count == 1 %}{% translate "Please correct the error below." %}{% else %}{% translate "Please correct the errors below." %}{% endif %}
</p>
{{ cl.formset.non_form_errors }}
{% endif %}
<div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
<div class="changelist-form-container">
{% block search %}{% search_form cl %}{% endblock %}
{% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %}
<form id="changelist-form" method="post"{% if cl.formset and cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %} novalidate>{% csrf_token %}
{% if cl.formset %}
<div>{{ cl.formset.management_form }}</div>
{% endif %}
{% block result_list %}
{% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %}
<!-- THIS LINE HAS BEEN CHANGED: -->
{% spamphoto_result_list cl %}
{% if action_form and actions_on_bottom and cl.show_admin_actions %}{% admin_actions %}{% endif %}
{% endblock %}
{% block pagination %}{% pagination cl %}{% endblock %}
</form>
</div>
{% block filters %}
{% if cl.has_filters %}
<div id="changelist-filter">
<h2>{% translate 'Filter' %}</h2>
{% if cl.has_active_filters %}<h3 id="changelist-filter-clear">
✖ {% translate "Clear all filters" %}
</h3>{% endif %}
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
</div>
{% endif %}
{% endblock %}
</div>
</div>
{% endblock %}
# spam/templates/admin/spam/spamphoto/change_list_results.html
{% load i18n static %}
{% if result_hidden_fields %}
<div class="hiddenfields">{# DIV for HTML validation #}
{% for item in result_hidden_fields %}{{ item }}{% endfor %}
</div>
{% endif %}
{% if results %}
<div class="container">
<div class="row">
{% for result in results %}
{% if result.form and result.form.non_field_errors %}
<div>{{ result.form.non_field_errors }}</div>
{% endif %}
<div class="col-sm-2">{% for item in result %}{{ item }}{% endfor %}</div>
{% endfor %}
</div>
</div>
{% endif %}

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.

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....

How to use different template for different browser

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>