In Django 1.7, I'm unable to provide a custom template. Instead it just defaults to the django_tables2/table.html
from django_tables2 import Table as BaseTable
class Table(BaseTable):
class Meta:
template = 'portal/base_table.html'
And my folder structure:
apps/portal/
├── __init__.py
├── tables.py
├── templates
│ └── portal
│ ├── base.html
│ ├── base_portal.html
│ ├── base_table.html
│ └── home.html
In the above, templates such as portal/base.html are resolved by template finders.
If I forego the Meta class and instead set:
from django_tables2 import Table as BaseTable
class Table(BaseTable):
template = 'portal/base_table.html'
I instead get the error TemplateDoesNotExist as it seems to be trying to resolve /data/www/apps/portal/templates/No template names provided among others.
To further support that I think the template should be resolving:
>>> render_to_response('portal/base_table.html')
<django.http.response.HttpResponse object at 0x7fa940c74690>
>>> render_to_response('portal/base_table.html2')
...
raise TemplateDoesNotExist(name)
TemplateDoesNotExist: portal/base_table.html2
My settings.py file contains:
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
path = lambda *a: os.path.join(BASE_DIR, *a)
TEMPLATE_DIRS = (
path('templates'),
)
This is working for all other templates such as for Views. Does django-tables2 not use the same lookup method?
In django tables2, for using custom template for providing custom template, you need to render it in templates like this:
<div class="">
{% load render_table from django_tables2 %}
{% render_table table 'portal/base_table.html'%}
</div>
You can check this answer as reference: Is it possible to apply a template tag to a <td> when using django-tables2?
As I ran into this Error with Django 1.8, and nobody seems to have the solution, for future reference this is how I solved it:
I had a manager that would be called as the default manager. This managers method get_queryset() was overwritten with a function to sort the resulting objects and return this list.
Turns out even though this is often seen in examples on the net and something similar is inside the documentation, you can only return a queryset there, not a list! Therefore just rename that function to anything else and you are allowed to return lists. Then you just call model.manager.anythingbutgetqueryset() and you are fine.
Add following setting to your settings.py file :-
TEMPLATE_DIRS = (
"path_to_your_template_directory",
)
Edit the path accordingly
Related
I have started learning Django recently and am following the code examples given in the tutorial of the Django site. Accordingly, I have created a site 'mysite' and an app 'books' in that site. Consequently, there are two 'views.py' files in the resultant directory structure - one in the 'mysite' folder and one in 'books' folder and there's only one 'urls.py' file - in the 'mysite' folder only. My question is the following - how do I avoid name conflicts for the functions that I create in the two 'views.py' files? If there are two functions with the same name in both the files, how does Django resolve which function to call for a given URL pattern in 'urls.py' file?
The following is my directory structure:
C:.
│ manage.py
│
├───books
│ admin.py
│ admin.pyc
│ models.py
│ models.pyc
│ tests.py
│ views.py
│ views.pyc
│ __init__.py
│ __init__.pyc
│
└───mysite
base.html
base_blog.html
base_welcome.html
currdate.html
settings.py
settings.pyc
urls.py
urls.pyc
views.py
views.pyc
wsgi.py
wsgi.pyc
__init__.py
__init__.pyc
An additional and related question - if I have multiple projects (like 'mysite') and different apps in those projects, how do I differentiate the URLs across the projects? I mean, currently, the URL http://127.0.0.1:8000/hello is mapped to a view function in 'mysite' project. What if I now have one more project, say 'mynewsite', how would Django resolve the URL http://127.0.0.1:8000/hello to the view function of 'mynewsite'? I hope my question is clear.
Thanks,
Rakesh.
In python you can import libraries (in this case file like views.py) one of them would be causing name conflicts you are talking about, namely
from books.views import my_view
from mysite.views import my_view
in that case, my_view will simply be overwritten. However, you can also do the following
import books.views
import mysite.views
In that case, to access the imported view, you will have to use full path, i. e. books.views.my_view, therefore there is no name conflict.
As for your other question, consider the following urls.py contents:
urlpatterns = patterns('',
url(r'^$', mysite.views.my_view, name='index'),
You can replace it with
urlpatterns = patterns('',
url(r'^$', books.views.my_view, name='index'),
I have two apps, consisting of adminApp and mobileApp. Both have their own template directory and totally seperated. Unfortunately django keeps looking in the wrong directory when i eg. use extend, it looks into the first template directory according to the order in INSTALLED_APPS:
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
INSTALLED_APPS = (
...
'adminApp',
'mobileApp',
...
)
My directory structure is:
adminApp/
templates/
base.html
mobileApp/
templates/
base.html
So basically what happens is that when i have a file such as mobileApp/templates/pages/index.html with a {% extends "base.html" %} it uses adminApp/templates/base.html instead of its own.
How can i avoid this and keep them separated?
Your apps don't follow the Django conventions for template directories. The app name should be repeated to avoid this issue:
adminApp/
templates/
adminApp/
base.html
mobileApp/
templates/
mobileApp/
base.html
You can then unambiguously specify which template you wish to extend:
{% extends "mobileApp/base.html" %}
I started with a django app and tried displaying an image in the home page. But the image is not getting displayed.
My settings.py:
MEDIA_ROOT = os.path.join(BASE_DIR,"media")
MEDIA_URL = "/media/"
My urls.py:
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'myapp.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'',include('users.urls')),
)
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
My home.html:
<html>
<head>
<title>MY SITE</title>
</head>
<body>
<img src="/media/image/myimage.jpg" alt="my image"/>
Welcome to my site
</body>
</html>
I get the text my image displayed instead of the image
ok, so I set up a simple 'paired-down' working example of this so no moving pieces were missing. Some Notes:
I used django 1.6
If you want to use a 'scale-able' delivery of static images you will want to follow
the django-1.6 staticfiles documentation which is what this example provides.
This means that you need to hack-n-slash your MEDIA references. ( MEDIA is really meant for file upload's) and you dont need to fool with the staticfiles_urlpatterns in your urls.py file. As you get this behavior out-of-the box when you add 'django.contrib.staticfiles' to your settings.py
Overview: Here is what your file tree-layout will look like in django 1.6, and the file structure that I am referencing in this answer.
├── djproj
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── wsgi.py
├── manage.py
└─── myapp
├── admin.py
├── __init__.py
├── models.py
├── static
│ └── myapp
│ └── myimage.jpg
├── templates
│ └── index.html
├── tests.py
└── views.py
Step 1: Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
Step 2: In your settings file, define STATIC_URL, for example:
STATIC_URL = '/static/'
Step 3: change your home.html to look like this ( I used index.html in my example )
[ PROJECT_HOME/myapp/templates/index.html ]
<html>
<head>
<title>MY SITE</title>
</head>
<body>
{% load staticfiles %}
<img src="{% static "myapp/myimage.jpg" %}" alt="My image"/>
Welcome to my site
</body>
</html>
Make sure to read the django-1.6 staticfiles documentation related to STATICFILES_STORAGE so you understand what these template tags are buying you. Hint: python manage.py collectstatic
Step 4: ( you may have already done this, but I did not see it) Make sure that TEMPLETE_DIRS is defined in your settings.py and includes your home.html ( key here is that django's template engine needs to be serving this as we will be using some template tags)
[ PROJECT_HOME/djproj/settings.py ]
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
BASE_DIR + '../myapp/templates',
)
Step 5: build a view that renders your home.html page.
[ PROJECT_HOME/myapp/views.py ]
from django.shortcuts import render_to_response
def index( request ):
return render_to_response('index.html')
Since this is a bit convoluted, and there are several moving pieces here: here is a changeset that shows the complete 'changes'
You can of-coarse pull the entire github project if any of this is confusing.
django-staticfiles-setupexample
Final Note: STATIC files were not always handled this way in django. The MEDIA dir used to be the settings attr you were after. So this answer is for Django 1.6 ( staticfiles were added in django version 1.3)( the directory layout was changed in django 1.5).
You can ( as you were trying to do) hardwire your media dirs to the STATIC defines. Altho I do-not recommend this. Which is why I did not describe how to do it this way.
You are adding the media urls too late in the list. Django will try to match each urlpattern in succession, stopping when it gets to the first one. In this case, it matches on r'' and doesn't get to the static files or the media urls.
You may be able to put each pattern in the single call to patterns(), instead of using +=. That would be the cleanest, but I can't test it here. A sure-fire way to do it would be to pull the "users.urls" line out and add it later, like so:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
)
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += url(r'',include('users.urls'))
I'd recommend you set DEBUG = TEMPLATE_DEBUG = True and request the image URL directly.
You'll get Django debug output either showing that the URL can't be matched or the file path it's actually looking for.
The settings look generally correct although you've not shared BASE_DIR which is important in this case.
I had been struggling with the issue for like an entire day yesterday... I finally gave up and moved on creating my site without worrying about the images. Then today I decided to check the responsiveness of the site. I found out that my URLs were okay since I had strictly been following the documentation and best practices. The chrome console was saying:
Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
The issue was with HTTP Referral Policy. Check them out. So after doing some research, this helped a lot, I found out that AdBlock was blocking my referred images. Apparently, my /media/ path was flagged in one of their regex patterns, deciding that my images were redirections to Ads. The ironic thing is that my website is about ads... so it must have heavily factored in, as my site has words like 'ad' in its url patterns. Long story short, I disabled AdBlock and my images now render. So I think it might be worth considering that even with best practices in your Django code, such an error could be caused by something with your browser!
I'm trying to create custom filters, and I've followed the steps in the Django documention.
However, when I load the template that loads the filters the following error is thrown:
'custom_filters' is not a valid tag library
...which refers to the line below in the template:
1 {% extends 'shared/base.html' %}
2 {% load custom_filters %} <--- the error
3
4 {% block title %}
5 Showing project {{project}}
6 {% endblock %}
The file structure:
project/
...
...
models.py
views.py
templates/
templatetags/
__init__.py
custom_filters.py
custom_filters.py:
from django import template
register = template.Library()
#register.filter(name='ownership')
def ownership(project, user):
return project.added_by_user == user
So, by some reason Django can't find the custom_filters file as it seems, even though I have done everything as one should (as far as I know).
What am I doing wrong?
NOTE: Of course I've tried to restart the server.
Template tags folder must be beside of templates folder, views.py, models.py, ...
//Don't forget also to put __init__.py outside the templatetags,
#register.simple_tag
def ownership(project, user):
return project.added_by_user == user
If your App name is MyApp and your tag folder name is templatetags then in settings.py you should have :
INSTALLED_APPS = [
'MyApp',
'MyApp.templatetags'
]
Both your app and your tag folder which is under your app package
Django Project are needed there.
-> MyApp
---> models.py
---> views.py
---> templatetags
-----> __init__.py
-----> app_filters.py
I have created a templatetags folder inside my application and inside a file named posts.py, I have written the following code;
from django.template import Library, Node
from advancedviews.models import Post
register = Library()
class AllPost(Node):
def render(self,context):
context['all_posts'] = Post.objects.all()
return ''
def get_all_posts(parser,token):
return AllPost()
get_all_posts = register.tag(get_all_posts)
Now, I try to load this template tag inside my template;
{% load get_all_posts %}
But this gives me with error, 'get_all_posts' is not a valid tag library: Template library get_all_posts not found, tried django.templatetags.get_all_posts,django.contrib.admin.templatetags.get_all_posts
What is the error in this template or have I missed something here.
With load you need to use the name of the library, not the tag - so posts in your case.
(I assume you also have a blank __init__.py in the templatetags directory, and that the application is in INSTALLED_APPS).
suppose you have the following structure:
-- Application_Name
-------templatetags
--------------__init__.py
--------------templates_extras.py
-------__init__.py
-------settings.py
-- manage.py
You have to make sure of the following:
your application itself inside which your "templatetags" is resident is actually installed in INSTALLED_APPS in settings.py (e.g. "Application_Name")
your tag module itself that exists inside "templatetags" is already installed in INSTALLED_APP in settings.py (e.g. "ApplicationName.templatetags.tempaltes_extras")
keep sure you have "__init__.py" under templatetags directory
you have to restart the server
In some cases you have to remove all generated *.pyc if it did not work then retry again