Django template URL function not matching in app - python

I have a Django project set up with an app called pub. I'm trying to set it up so that I can include urls.py from each app (there will be more as I go) in the top-level urls.py. I've also got a template that uses the 'url' function to resolve a URL on a view, defined in the openidgae module. The problem is that after the httprequest is routed to pub.views.index (like it's supposed to), I try to respond by rendering a template that uses the template 'url' function. The code I'm showing below is also here: http://gist.github.com/243158
Here's my top-level urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', include('openidgae.urls')),
(r'^pub', include('pub.urls')),
)
and pub/urls.py:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', 'pub.views.index'),
(r'^/$', 'pub.views.index'),
)
and templates/base.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="header">
{% if lip %}
Welcome {{ lip.pretty_openid }}
logout
{% else %}
<form id="login-form" action="{% url openidgae.views.OpenIDStartSubmit %}?continue={{continueUrl}}" method="post">
<input type="text" name="openid_identifier" id="openid_identifier" />
<input type="submit" value="Verify" />
</form>
<!-- BEGIN ID SELECTOR -->
<script type="text/javascript" id="__openidselector" src="https://www.idselector.com/selector/46b0e6d0c8ba5c8617f6f5b970865604c9f87da5" charset="utf-8"></script>
<!-- END ID SELECTOR -->
{% endif %}
</div>
{% block content %}{% endblock %}
</body>
</html>
and templates/pub/index.html:
{% extends "base.html" %}
{% block title %}blahblah!{% endblock %}
{% block content %}
blahblahblah
{% endblock %}
and finally, pub/views.py:
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django import forms
import openidgae
def index(request):
lip = openidgae.get_current_person(request, HttpResponse())
resp = render_to_response('pub/index.html', {'lip': lip})
return resp
Now, if i set the second pattern in my top-level urls.py to point directly to 'pub.views.index', all works like it should, but not if I use the include function.
Any ideas? I'm sure the problem has something to do with the urlpattern that would map the views I'm trying to resolve to URLs not being available to the template rendering functions when the HttpRequest is handled by the pub app rather than by the top-level, but I don't understand why or how to fix it.

I don't understand what the problem is that you're facing, but just by looking at your urls.py files, you should probably change the top level urls.py to something like
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'', include('openidgae.urls')),
(r'^pub/', include('pub.urls')),
)
and pub/urls.py to:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^$', 'pub.views.index'),
)
if you then use {% url pub.views.index %} somewhere in your templates, you should get the correct url.

You post a lot of code, but you haven't been very clear about what the actual problem is. First of all having
(r'', 'pub.views.index'),
(r'^/$', 'pub.views.index'),
can give some problems if you want to find the url. What should the url be for pub.views.index? From what you say, this is actually not be a problem, since you don't have a template tag that want to reverse the mentioned view. You don't actually say what is going wrong. But a way to fix the above problem, if you want to keep the two urls, would be to used named urls. I find it a bit redundant since you can just redirect example.com/pub to example.com/pub/, but you could transform the above to:
url(r'', 'pub.views.index' name='pub_a'),
url(r'^/$', 'pub.views.index', name='pub_b'),
Doing this you are now able to reverse your url, as you can uniquely identify them doing {% url pub_a %} or {% url pub_b %}. This would also make your templates easier to read, as you can give names that mean something, so it's easier to remember what's going on, while being more concise.

Related

Explanation on Django's request processing - Why does it select one urlpattern from another

So I am doing an free online course that involves Django and have run into something that is rather confusing regarding how Django processes requests. My Django application has a single module and within this module I have essentially two pages that I am generating both of which inherit from a layout template. There is an index page (which contains links to individual entries) and an entry page which displays the content of each individual entry. There are two ways to get to an entry page. You could either directly click on the link that is present on the index page or you could type in the search bar that is present on index page. If the name matches the entry in the search bar it will take you to that entry page. Each method of reaching an entry page has its own url pattern in the urls.py file and each one has its own route function in the views.py file. What was happening was that regardless of what was typed into the search bar, it would only use the route that was meant for directly clicking on the entry link from the index page rather than the route that was meant for searching. Here are my html files:
layout (contains the nav bar for searching:
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'encyclopedia/styles.css' %}" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="sidebar col-lg-2 col-md-3">
<h2>Wiki</h2>
<form action="{% url 'encyc:search' %}" method="GET">
<input class="search" type="text" name="q" placeholder="Search Encyclopedia">
</form>
<div>
Home
</div>
<div>
Create New Page
</div>
<div>
Random Page
</div>
{% block nav %}
{% endblock %}
</div>
<div class="main col-lg-10 col-md-9">
{% block body %}
{% endblock %}
</div>
</div>
</body>
</html>
index page:
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>All Pages</h1>
<ul>
{% for entry in entries %}
<li>{{ entry }}</li>
{% endfor %}
</ul>
{% endblock %}
and the entry page:
{% extends "encyclopedia/layout.html" %}
{% block title %}
{{ name }}
{% endblock %}
{% block body %}
{{ entry | safe }}
{% endblock %}
Here is my urls.py file:
from django.urls import path
from . import views
app_name = "encyc"
urlpatterns = [
path("", views.index, name="index"),
# variable names for each page
path("<str:name>", views.display, name="display"),
path("search", views.search, name="search")
]
Here is my views.py file:
from django.shortcuts import render
import markdown2
from . import util
import logging
logging.basicConfig(filename='encyclopedia/log.log', encoding='utf-8', level=logging.DEBUG)
def index(request):
return render(request, "encyclopedia/index.html", {
"entries": util.list_entries()
})
def display(request, name):
logging.debug('request info: ')
logging.debug(request)
logging.debug('request path info: ')
logging.debug(request.path_info)
# convert name to all lowercase and then capitalize
entry = util.get_entry(name.lower().capitalize())
if (entry != None):
entry = markdown2.markdown(entry)
return render(request, "encyclopedia/entry.html", {
"name": name,
"entry": entry
})
else:
return render(request, "encyclopedia/error.html")
def search(request):
logging.debug('request info: ')
logging.debug(request)
logging.debug('request path info: ')
logging.debug(request.path_info)
name = request.GET['q'].lower().capitalize()
entry = util.get_entry(name)
entry = markdown2.markdown(entry)
return render(request, "encyclopedia/entry.html", {
"name": name,
"entry": entry
})
Here is the urls.py file for the entire Django application:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls")),
path('wiki/', include("encyclopedia.urls"))
]
Ultimately the fix here was in my urls.py file for individual module. The line
path("<str:name>", views.display, name="display")
should have been
path("wiki/<str:name>", views.display, name="display")
This began my quest to understand what was happening and why that worked. After digging into Django's documentation on request processing, it appears as if Django takes a request, scans the url patterns, and picks the first match based on a 'path_info' attribute. So now I know that the reason it was only using the display route rather than the search route is that it was somehow matching this attribute to that route and was never actually reaching the search urlpattern. This begs the question of why was it matching based on 'path_info'. I decided to set up a logger and take a look at what the request info was and the path_info. Here is a log for before the fix was implemented:
DEBUG:root:<WSGIRequest: GET '/CSS'>
DEBUG:root:request path info:
DEBUG:root:/CSS
DEBUG:root:request info:
DEBUG:root:<WSGIRequest: GET '/search?q=css'>
DEBUG:root:request path info:
DEBUG:root:/search
and here is the log after the fix was implemented
DEBUG:root:request info:
DEBUG:root:<WSGIRequest: GET '/wiki/CSS'>
DEBUG:root:request path info:
DEBUG:root:/wiki/CSS
DEBUG:root:request info:
DEBUG:root:<WSGIRequest: GET '/search?q=css'>
DEBUG:root:request path info:
DEBUG:root:/search
It appears to me that the path info is nothing more than the route that was specified in the url pattern. I still don't see why this fix works. Why does prepending 'wiki/' to my display route urlpattern allow for Django to now properly match the path_info when it couldn't before. Another question is why doesn't Django use the name attribute that was specified in the urlpattern to match the desired route? I specified in the html that I wanted the url for 'search' but it still selected the url for 'display'. If it were to just match the name that I had provided shouldn't this clear any ambiguity in selecting the appropriate url? I know this is a long winded post but any insight into how Django is processing these requests and why this specific fix worked for me would be greatly appreciated!
I think 2 steps need to be seperated:
rendering ot the {% url .... %} tag in the html which leads to the final url in the page
dispatching the request when the user clicks on the url
Both is linked to urls.py->path
Ad 1) for the display hrefs your urls is "reverse" created according to the name "display" and the attribute which you also called "name" in the path match string. So {% url "display" "css" %} leads to "server_name/css".
The search field does exactly the same via the path definition with the name"="search".
So everything is ok up to this point You see the correctly created urls/requests in your DEBUG data.
Ad 2) upon a request django gets only the url called and goes step by step through all your path statements to find a match.
Here is your problem because your patterns are not unique:
path("<str:name>", ....
will match /css but also /search?... because str matches any following string including "search?...".
You need to first to choose the target and then give the parameter like
Path("display/<str:parameter>" .....
Path("search" ... )
Then search is not matched by the preceding display path anymore.

Django malformed views.py or urls.py (redactor app)

I’m trying to write a web app which accepts a website visitor’s input which is a 12 digit “Chuckee Cheese” membership card number and then redacts the first 8 digits and presents the redacted number. I’ve got my template written and the basic logic inside my app’s views.py. The problem now is that after the user enters his or her card number, Django is not processing the user input properly. Like, the redacted number is not being presented and served in the template as intended.
Here is a pic on imgur showing my website running on my dev server now. As you can see in that pic, in the web address bar Django receives the ‘ccEntry’ GET Request with ‘123456789102’ as user input. So I guess that kind of works. But below the two h1 elements (in lime green), Django should show the card number ‘123456789102’ as well as the redacted card number ‘xxxx xxxx 9102’ but instead it’s blank. What is wrong here? As far as I can tell, I believe the problem involves either the first two functions inside my redactors views.py or the way my app’s urls.py is arranged.
Here is my views.py :
from django.shortcuts import render
# Create your views here.
def redactors(request):
return render(request, 'alls/landings.html')
def home(request):
if 'ccEntry' in request.GET:
number = request.GET['ccEntry']
redacted_num = 'xxxx xxxx {}'.format(number[-4:])
return render(request, 'alls/landings.html', {'number':number, 'redacted_num':redacted_num})
else:
return render(request, 'alls/landings.html')
def results(request):
return render(request, 'alls/landings.html')
Here is my app’s urls.py:
from django.urls import path, include
from . import views
urlpatterns = [
path('home', views.home, name='home'),
path('results', views.results, name='results'),
]
Those are the two scripts where I believe the problem is.
For what it is worth, here are some other related configuration files and scripts that are in play:
Lightly abbreviated alls/landings.html template:
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="The HTML5 Herald">
<meta name="robots" content="noindex,nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Custom -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
{% block content %}
<div class="card-processor">
<h3>Enter your fake Chuckee Cheese Neptune membership card number!</h3>
<form action="{% url 'posts' %}" method="get">
<div>
<label for="password">Enter Card Number:</label>
<input type="text" id="password" name="ccEntry" pattern="[0-9]{12}" maxlength="12"/>
<div class="requirements">Must be a 12 digit number and no letters. </div>
<input type="submit" value="Redact!" class="button"/>
</div>
</form>
<h1>Here is your fake Chuckee Cheese Neptune memnership card number!</h1>
<h3 style="color:lime">This was the original number that you entered:</h3>
<div class="field">{{ number }}</div>
<h3 style="color:lime">Here it is redacted:</h3>
<div class="field">{{ redacted_num }}</div>
<div class="field"><strong>Again? Click here!</strong></div>
</div> <!--- END card-processor -->
<div class="post-content">
{% for post in posts %}
<h1> Blog post title: <em>{{ post.title }}</strong></em>
<h4>Publication Date: {{ post.pub_date_preference }}</h4>
<img src="{{ post.image.url }}" class="authors-pic" style="" />
<!-- Body text should go here : -->
<p>{{ post.body|safe }}</p>
{% endfor %}
{% endblock %}
</body>
</html>
Parent urls.py router:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('posts.urls')),
path('', include('redactors.urls')),
path('', include('counters.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I believe those are all the relevant files in play. However in case the problem is elsewhere, if you want to see the rest of my source code, here is a static snapshot tagged as v.0.7.0 on my GitHub.
It's also worth noting that I'm not getting a trace back and my server is not crashing so I don't have many leads in terms of searching on Google for other developers resolving similar or related issues.
It seems like the 'form' in landings.html is being submitted to the path with name "posts", But there is no path with this name in your app's urls.py.
Use this <form action="{% url 'home' %}" method="get"> instead of <form action="{% url 'posts' %}" method="get">.

Rendering different templates to the same URL pattern in Django

My question is similar to Same URL in multiple views in Django, but I am not rendering templates on the basis of user_authentication, but rather on the basis of JavaScript enabled or disabled in the browser.
What I am trying to do?
I am trying to render the index.html page if JavaScript is enabled in the browser, otherwise I want to render jsDisabled.html page if it's disabled and both of the pages should be rendered on the same URL pattern, for example:
localhost:8000 should either render index.html if JavaScript is enabled in the browser or it should render jsDisabled.html page if JavaScript is disabled.
Note: I am checking if JavaScript is disabled in the browser by using the <noscript> tag which will run when JavaScript is disabled.
Here is my code so far:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body class="noJs">
...
abc
...
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
<meta http-equiv="refresh" content="{% ulr 'index' 1 %}"> /* This should render jsDisabled.html page on the same URL which is 'localhost:8000' */
</noscript>
</body>
</html>
urls.py:
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
...
url(r'^(?P<flag>[0-1])$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request, flag):
if (flag):
return render(request, 'jsDisabled.html')
else:
return render(request, 'index.html')
Depending on your Django version you may need to specify TEMPLATE_DIR = in settings.py (in newer versions this isn't required).
Here is some helpful information on template and tag logic:
Main/templates/myapp/base.html
Main/templates/myapp/index.html
Main/templates/myapp/includes/yes_js.html
Main/templates/myapp/includes/no_js.html
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
index.html:
{% extends 'myapp/base.html' %}
{% load staticfiles %}
{% block content %}
<noscript>
{% include 'no_js.html' %}
</noscript>
{% include 'yes_js.html' %}
{% endblock %}
After a lot of debugging I finally found the solution :) And here it is:
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="noJs">
...
abc
...
</div>
<noscript>
<style type="text/css">
.noJs {
display: none;
}
</style>
{% include 'includes/jsDisabled.html' %}
</noscript>
</body>
</html>
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^articles/', include('articles.urls')),
url(r'^contact/', include('contact.urls')),
url(r'^temp/',views.temp, name="temp"),
url(r'^$', views.index, name='index'),
]
views.py:
from django.shortcuts import render
def index(request):
return render(request,'index.html')
def temp(request):
return render(request,'temp.html')
I included the include built-in template tag as {% include 'includes/jsDisabled.html' %} suggested by #noes1s by creating a folder named includes inside the templates folder and placing jsDisabled.html inside of it.

Is there a simple way to display mysql data in Django template without creating an app?

I have a table in my MySQL database named mysite_categories, there are 4 columns but for my purposes I just need two (name, base_url).
I currently have a template '*base_categories.html*' that I use to load the categories manually.
base_categories.html (trimmed down)
{% block content %}
<div class="section" style="float: right;">
<h4 class="gradient">Category List</h4>
<ul>
<li>Art</li>
<li>Biography</li>
<li>Science</li>
</ul>
</div>
{% endblock %}
What I'd like to do is pull the data from the db and use it in a for loop. Something like:
{% block content %}
<div class="section" style="float: right;">
<h4 class="gradient">Category List</h4>
<ul>
{% for category in mysite_categories %}
<li>{{ category.name }}</li>
{% endfor %}
</ul>
</div>
{% endblock %}
This is probably a newbie question but is it possible to something like this without creating an app?
*EDIT 1*
These are my app files, I'll admit this is probably junk, I have tried so many edits from so many different posts I'm sure I've broke it somewhere :P. I was going to remove it and start fresh but I figure I might as well post it to see where I might have gone wrong?
views.py
from django.shortcuts import render_to_response
from categories.models import categoryList
def index(request):
categories = categoryList.objects.all()
extra_context = {"categories": categories}
return render_to_response("myapp/index.html", extra_context)
models.py
from django.db import models
class categoryList(models.Model):
#id = models.IntegerField(unique=True, db_column='ID') # Field name made lowercase.
name = models.CharField(max_length=255L, unique=True)
base_url = models.CharField(max_length=255L, unique=True)
thumb = models.CharField(max_length=1L, unique=True, blank=True)
class Meta:
db_table = 'mysite_categories'
index.html
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<div class="section" style="float: right;">
<h4 class="gradient">Category List</h4>
<ul>
{% for category in categories %}
<li>{{ category.title }}</li>
{% endfor %}
</ul>
</div>
As mentioned, it's probably junk at this point, if any of you can help me straighten this out it would be appreciated!
*EDIT 2*
base_right_panel.html
{% block content %}
<div style="float: right;">
<div id="base_categories" style="margin: 10px; padding-bottom: 10px;">
{% block base_categories %}
{% include "base_categories.html" %}
{% endblock %}
</div>
</div>
{% endblock %}
*Edit 3*
base_categories.html
{% block content %}
<div class="section" style="float: right;">
<h4 class="gradient">Category List</h4>
<ul>
{% if categories %}
{% for category in categories %}
<li>{{ category.title }}</li>
{% endfor %}
{% else %}
<p>no data! {{ categories|length }}</p>
{% endif %}
</ul>
</div>
{% endblock %}
*EDIT 4*
(Application name was changed to CategoryList)
CategoryList/views.py
from django.views.generic import TemplateView
from CategoryList.models import CategorylistCategorylist #<-- Changed to match inspectdb result
class IndexView(TemplateView):
template_name="categorylist.html" #<-- Changed name from index.html for clarity
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context["categories"] = CategorylistCategorylist.objects.all()
return context
CategoryList/models.py
from django.db import models
class CategorylistCategorylist(models.Model): #<-- Changed to match inspectdb
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255L, unique=True)
base_url = models.CharField(max_length=255L, unique=True)
thumb = models.ImageField(upload_to="dummy", blank=True) #<-- Ignored inspectdb's suggestion for CharField
def __unicode__(self):
return self.name
# Re-added Meta to match inspectdb
class Meta:
db_table = 'categorylist_categorylist'
CategoryList/urls.py
from django.conf.urls.defaults import patterns, url, include
from django.contrib import admin
from django.conf import settings
from CategoryList import views
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='categorylist'),
)
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns
MySite/urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.conf import settings
from home import views as home_view
from CategoryList import views as index_view
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', home_view.HomeView.as_view(), name="home"),
url(r'^categories/$', index_view.IndexView.as_view(), name='categorylist'),#include('CategoryList.urls')),
url(r'^admin/', include(admin.site.urls)),
#url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
)
if settings.DEBUG:
urlpatterns = patterns('',
url(r'^media/(?P<path>.*)$', 'django.views.static.serve',
{'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),
url(r'', include('django.contrib.staticfiles.urls')),
) + urlpatterns
So far I can load the url "localhost:8000/categories" and I will see the list of category names appear on the right side of the screen as expected, but there is no template formatting applied. Inside my "*base_right_panel.html*" file I've tried "{% include "categorylist.html %}" to link directly to the application, which displays the correct template formatting, but displays the "{% else %}" response from "{% if categories %}" instead of the categories? I have tried changing the include to point to "categories/", which works in the browser, but it tells me it cannot find the template?
I'm sooo stumped right now..?
This answer is not meant to disagree with Alasdair's - it's just to add some more information on working with templates.
The core handler of an HTTP request to a Django application is the view. The view receives the HTTP request, as well as any arguments captured from the URL, and is responsible for returning an HttpResponse instance (or an instance of one of its subclasses) which will be returned to the browser.
The view is not bound to use any particular method to create the HttpResponse. Rendering a template to include information derived from the database and from request information or URL arguments is sufficiently common that there's code to support it, like the render shortcut or its mostly obsolete antecedent render_to_response, but this is by no means required. It's perfectly legitimate to have a view directly construct the HttpResponse:
def index(request):
return HttpResponse('This is an index page.')
Or, for very simple HTML:
def index(request):
return HttpResponse('<html><head><title>example</title></head><body>This is an index page.</body></html>')
In practice, I have often created HttpResponse instances directly to return json data or a dynamically created PDF or Excel file.
A simple way to slot information retrieved from the database into your response would be to use Python's built-in string interpolation:
def index(request):
return HttpResponse('Hello, %s' % request.user.email)
Or you could use the advanced string formatting options:
def index(request):
user_names = {}
user_names['first_name'] = request.user.first_name
user_names['last_name'] = request.user.last_name
return HttpResponse('Hello, %(first_name)s %(last_name)s' % user_names)
All this is building up to the point that it doesn't matter how you generate the text contents of your HttpResponse. All that matters is that you return one.
The template system is a powerful and extensible tool for generating text content, but that's all it does. If you look at the template docs about rendering a template, you'll see some examples that are almost exactly the same as the the string interpolation above.
render_to_response was a shortcut that would accept a template and a context and return an HttpResponse with the rendered contents of that template and context. Skipping over its context_instance and content_type parameters for the sake of demonstration, these two code blocks are identical in effect:
def index(request):
t = Template('Hello, {{ first_name }} {{ last_name }}')
c = Context({'first_name': request.user.first_name, 'last_name': request.user.last_name})
response_text = t.render(c)
return HttpResponse(response_text)
Assume a template index.txt exists as defined below, at the top level of an entry in the setting's TEMPLATE_DIRS tuple.
index.txt
Hello, {{ first_name}} {{ last_name}}
Then the view above could be replaced with:
def index(request):
t = get_template('index.html')
c = Context({'first_name': request.user.first_name, 'last_name': request.user.last_name})
response_text = t.render(c)
return HttpResponse(response_text)
Alternatively, you can skip the explicit creation of the context object and rendering of the template into a string thus:
def index(request):
return render_to_response('index.html', {'first_name': request.user.first_name, 'last_name': request.user.last_name})
On more recent versions of Django you should generally use the render shortcut rather than render_to_response - the details are a bit too much to go into if you're still struggling with getting context into your templates.
def index(request):
return render('index.html', {'first_name': request.user.first_name, 'last_name': request.user.last_name})
Of course, part of what makes templates useful is that the rendering engine can perform certain kinds of logic and lookup. I don't actually need to explictly keep looking up first_name and last_name - I can just pass in request as part of my context and look up its attributes in the templates:
index_showing_context.html
Hello, {{ request.user.first_name }} {{ request.user.last_name }}
def index_showing_context(request):
return render('index_showing_context.html', {'request': request})
Even passing in request isn't strictly necessary in that example, because one of the differences between render and render_to_response that I alluded to above is that request is always part of the context for render. But, again, that's an advanced subject.
So for your particular problem, it really doesn't matter where in your templates you render the data you want, as long as you have provided it to your view's context and are rendering the correct template. The template is in effect just a file name used to find and build a string, into which your context will be interpolated.
The {% include %} template tag is one way to mix template fragments into other templates. If I wanted to, I could set mine up like this:
header.html:
<head>
<title>This is a sample title.</title>
</head>
index.html:
<html>
{% include "header.html" %}
<body><p>This is my template body, {{ request.user.first_name }} {{ request.user.last_name }}.</p></body>
</html>
detail.html:
<html>
{% include "header.html" %}
<body><p>This is a detail page, probably for something selected in the context and given the context key 'object'.</p>
<p>{{ object }}</p>
</body>
</html>
That works fine, but it's not the only option. From your question, I see that you're using blocks and template inheritance. A common idiom is to define a base template that all or almost all other templates will inherit from:
base.html
<html>
<head>
<title>{% block title %}Default title{% endblock %}</title>
{% block extra_head_elements %}{% endblock %}
</title>
<body>
{% block body_header %}Standard page header here {% endblock %}
{% block body_content %}{% endblock %}
{% block body_footer %}Standard page footer here {% endblock %}
</body>
</html>
index.html
{% extends "base.html" %}
{% block title %}index {% endblock %}
{% block body_content %}<p>This is my template body, {{ request.user.first_name }} {{ request.user.last_name }}.</p>{% endblock %}
detail.html
{% extends "base.html" %}
{% block title %}detail{% endblock %}
{% block body_content %}<p>This is a detail page, probably for something selected in the context and given the context key 'object'.</p>
<p>{{ object }}</p>
{% endblock %}
So ultimately, I am not quite sure how you should best stitch together your right panel concept because it depends on the way you want your pages to work. If it's going to be present everywhere or almost everywhere, I would recommend putting it into a base template that the rest of your templates will extend. If you want it on exactly one page, just literally include it in that template. If you want it on some but not all pages, a template fragment that you can {% include %} is probably best.
The main thing is to understand how the template engine will compose your {% include %} and {% extends %} tags, and to provide the necessary data to the template's context in your view.
Edit:
If I wanted to have a view and template pair that just retrieved the categories, this is a simple way to lay it out using your example model code and rendering. There are other options.
index.html
<html>
<head><title>Simple category listing</title></head>
<body><p>The categories are:</p>
<ul>
{% for category in categories %}
<li>{{ category.name }}</li>
{% endfor %}
</ul>
</body>
</html>
view:
def index(request):
categories = categoryList.objects.all()
extra_context = {"categories": categories}
return render_to_response("index.html", extra_context)
If I wanted to reuse the category listing on multiple pages, that gets back into the include vs. extends discussion above. Either way, the template will always require your view to pass in categories as a context variable.
You could execute custom SQL directly to fetch categories in your view, and loop through the output in your template. This would not require an app.
If you create a model, you will be able to use the Django queryset api, which is very convenient, e.g.
mysite_categories = Category.objects.all()
This does require you to create an app. However, creating an app is really easy, just use the startapp command.
python manage.py startapp myapp
Once you've created your app, you can use the inspectdb command to inspect your database, and create a model for your mysite_categories table.

placeholder not working in django-cms

I am using django cms to develop a site, configured everything and working fine,and below are my code files
settings.py
........
........
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.i18n',
'django.core.context_processors.request',
'django.core.context_processors.media',
'django.core.context_processors.static',
'cms.context_processors.media',
'sekizai.context_processors.sekizai',
)
CMS_PLACEHOLDER_CONF = {
'terms_and_conditions': {
'name': gettext('Terms & Conditions'),
'plugins': ['TextPlugin'],
},
}
CMS_TEMPLATES = (
('home.html', 'Home Page'),
)
........
.......
urls.py
from django.conf.urls import patterns, include, url
from django.conf.urls.defaults import *
from django.conf.urls.i18n import i18n_patterns
from django.conf import settings
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('cms.urls')),
)
base.html
{% load cms_tags sekizai_tags menu_tags %}
<html>
<head>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome to Services</title>
{% render_block "css" %}
</head>
<body>
{% cms_toolbar %}
<div class="promoinner">
{% block base_content %}{% endblock %}
</div>
{% render_block "js" %}
</body>
</html>
home.html
{% extends "base.html" %}
{% load cms_tags %}
{% block base_content %}
{% placeholder "terms_and_conditions" or %}
<p>This data should be present in the editor in editing mode before entering anything in to plugins, because this data is giving through html</p>
<p>But when i tried to edit the placeholder i cant see the data(that we mentioned in tags of html file), i can able to see the placeholder and i can able to add some data in to text plugin </p>
{% endplaceholder %}
{% endblock %}
Here all the problem is, we are giving some data through p tags in html file, so when i opened the url http://localhost:8000/?edit, i can able to see the placeholder named as
Terms & Conditions as we mentioned in the settings.py file, but the data we given in html file through tags is not editable and cant be seen, at the same time i can able to add some text in to placeholder using text plugin.
Can anyone please let me know why the data that mentioned through html tags in home.html is not editable and even cant be seen ?
try to load the placeholder tags in "base.html" or "home.html" like(looks like your missing "placeholder_tags")...
{% load cms_tags sekizai_tags menu_tags placeholder_tags %}

Categories

Resources