Rendering different templates to the same URL pattern in Django - python

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.

Related

'QuerySet' object has no attribute 'META' 500(internal server erro)

I'm trying to practice ajax in django but I got this error 'QuerySet' object has no attribute 'META'. But it's showing the data in the traceback but not in the template because of the error.How to fix this?
models.py
from django.db import models
# Create your models here.
class Profile(models.Model):
name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
bio = models.CharField(max_length=100)
def __str__(self):
return self.name
I think it has something to do with the views but I cant figure it out.
views.py
from django.shortcuts import render
from .models import Profile
from django.http import JsonResponse
# Create your views here.
def list(request):
return render(request, 'livedata/list.html')
def getProfiles(request):
profiles = Profile.objects.all()
# print(JsonResponse({"profiles": list(profiles.values())}))
return JsonResponse({"profiles": list(profiles.values())})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.list, name='list'),
path('getProfiles', views.getProfiles, name='getProfiles')
]
index.html
{% load static %}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
{% comment %} <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> {% endcomment %}
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script src="{% static 'js/main.js' %}" defer></script>
<title>Hello, world!</title>
</head>
<body>
{% block contents %}{% endblock contents %}
{% block scripts %}{% endblock scripts %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
{% comment %} <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> {% endcomment %}
{% comment %} <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> {% endcomment %}
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
</body>
</html>
list.html
{% extends 'livedata/index.html' %}
{% block contents %}
<h1>List of live data</h1>
<ul id="display">
</ul>
{% endblock contents %}
{% block scripts %}
<script>
$(document).ready(function () {
setInterval(function () {
$.ajax({
type: 'GET',
url: "{% url 'getProfiles' %}",
success: function (response) {
// console.log(response);
$("#display").empty();
for (var key in response.profiles) {
var temp = "<li>" + response.profiles[key].name + "</li>";
$("#display").append(temp);
}
},
error: function (response) {
alert("Error occured");
}
});
}, 1000);
});
</script>
{% endblock scripts %}
You should not name a view list, list is a builtin function that you use in other views. By defining a view named list, the list(profiles.values()) will call the view with profile.values() as the request.
Rename list to view_list for example and update the url patterns to direct to view_list instead:
def view_list(request):
return render(request, 'livedata/list.html')
def getProfiles(request):
profiles = Profile.objects.all()
# does not refer to the view &downarrow; but to the list builtin
return JsonResponse({"profiles": list(profiles.values())})
The urls.py thus looks like:
from django.urls import path
from . import views
urlpatterns = [
path('', views.view_list, name='list'),
path('getProfiles', views.getProfiles, name='getProfiles')
]

django url tag, not a valid view function or pattern name

I tried to link an anchor to another page in Django. But I get the error " Reverse for 'animals.all_animals' not found. 'animals.all_animals' is not a valid view function or pattern name."
I tried several ways to do it.. no success. I have one app called animals and Im tyring to display the list of animals in the by clicking an anchor on the homepage. I attached here my Django files.
from django.shortcuts import render, get_object_or_404
from .models import Animal
def animal_list(request):
animals = Animal.objects.all()
return render(request, 'animals/animal_list.html', {'animals': animals})
// and here is the html
{% for animal in animals %}
<h1>{{animal.species}}</h1>
<p>{{animal.description}}</p>
{% endfor %}
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.animal_list, name='all_animals'),
url(r'^(?P<pk>\d+)/$', views.animal_detail, name='all_details'),
]
{% load static from staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animals Site</title>
<link href="{% static 'css/base.css'%}" rel="stylesheet">
</head>
<body>
{% block content %}
<nav>
Animal List
</nav>
<a></a><h2>I love cats!</h2>
{% endblock content %}
{% block listbar %}
<ul>
<li>Sphynx</li>
<li>Catto</li>
<li>Bengal</li>
</ul>
{% endblock listbar %}
</body>
</html>
{% block listcolor%}
<style>
h2{
font-family: 'Calibri';
color: blue;
}
</style>
{% endblock listcolor%
You need a colon not a dot in the notation:
Animal List
Or in case the included urls from your app are not namespaced:
Animal List

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 %}

Django template inheritance delivers no css?

In my django project there are some mysterious (at least for me as a beinner) outputs I don't understand while working in my development environment.
I wanted to have a base template which includes a stylesheet in a static media folder...this works so far...but just for the address http://localhost/ all the other urls have a template which inherits from the base template.
Now the stylesheet of http://localhost/ looks nice...if i go to http://localhost/hello/ the included stylesheet has a whole html DOM structure with body, doctype etc. why is that? He somehow parses a html site instead of taking the css file...
Here my code: Any ideas?
urls.py:
from django.views.static import *
from django.conf import settings
admin.autodiscover()
urlpatterns = patterns('',
('^$',home_view),
('^hello/$', hello),
(r'^admin/', include(admin.site.urls)),
('^useragent/$',ua_display_good1),
(r'^media/(?P<path>.*)$', 'django.views.static.serve',
)
views.py
from django.http import HttpResponse
from django.shortcuts import render_to_response
def hello(request):
pagetitle = "Hello World"
return render_to_response('hello.tpl', {'pagetitle': pagetitle})
def home_view(request):
pagetitle = "Something"
return render_to_response('home.tpl', {'pagetitle': pagetitle})
def ua_display_good1(request):
try:
ua = request.META['REMOTE_ADDR']
except KeyError:
ua = 'unknown'
return render_to_response('base.tpl',{'ageone': ua})
base template:
<!DOCTYPE html>
<html lang="de">
<meta name="description=" content="{{metadescription}}">
<head>
<link rel="stylesheet" type="text/css" href="media/style.css">
<title>{% block title %}{{pagetitle}}{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{{ageone}}{% endblock %}</h1>
{% block content %}{% endblock %}
{% block footer %}{% include "footer.tpl" %}
{% endblock %}
</body>
</html>
hello template:
{% extends "base.tpl" %}
{% block h1 %}Home{% endblock %}
{% block content %}Welcome{% endblock %}
Probably because you have a relative reference to the CSS file.
Try changing:
<link rel="stylesheet" type="text/css" href="media/style.css">
to
<link rel="stylesheet" type="text/css" href="/media/style.css">
so it always look in the root for media/style.css
Now you have set the link to css as relative "media/style.css". In home it resolves to "/media/style.css" but in hello it resolves to "/hello/media/style.css" (which gives the hello page).
Just use absolute css link like this: "/media/style.css".
The proper way to include the style sheets would be
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}style.css">
if this still wont work ....my css file name is Stylesheet.css and i linked it as css/Stylesheet.css ..it wasnt working... then i changed it to css/Stylesheet.CSS ..and it worked
Change href="media/style.css" to href="media/style.CSS" and it will work.

Django template URL function not matching in app

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.

Categories

Resources