Django template is not changed after update (possible cache) - python

I have a problem with Django. Possibly with it's cache. Version 1.11
I use template in urlpatterns like :
urlpatterns = [
url(r'^service_preview/', include(serviceprev_urls, namespace = 'service_preview')),
url(r'^service_preview/',TemplateView.as_view(template_name='service_preview.html')),
]
After a lot of updates, applied to my template, the changes stop appearing in user's browser. I have actual template in my templates folder and some previous version when preview source code in browser. If I rename the template (this should raise error because template is absent), I still have that previous template in browser source. Browser page refreshing, clearing browser cache etc does not help. There are no duplicates of this page in my template folder.
When I use another template, all is ok.
Possibly, problem is in django cache. I don't know how to force clear cache, maybe it would be a solution.
I put this at app setting file, but it doesn't help.
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.dummy.DummyCache',}}
EDIT:
i found i have duplicate html name, located in the same project, but other application's template directory. May it cause a problem

By default, the Django template loader caches templates when DEBUG = False. After changing a template, you need to restart the server (e.g. Apache or gunicorn) to see the changes. This behaviour is not affected by the CACHES setting.

Related

Django: using html templates TemplateDoesNotExist

I've been writing my first Django app and hit a problem with using templates.
No matter how I format the url for the template I receive the TemplateDoesNotExist error.
My html is nest in views/ with the core template being views/template.html.
I have tried:
myapp/views/template.html
views/template.html
templates/views/template.html
<full path to app>/<all variations>
None of which can locate the template.
I understand the TEMPLATE_DIRS variable may be set at project level but this is app-specific and the views/ directory is not purely for templates.
I don't think I should add to the url_patterns since the template shouldn't be accessible directly.
I've got this far without them but need to clean up the app.
Any advice?
Edit:
The only line in my controller currently is:
template = loader.get_template("test/templates/test/template.html")
The line has been tested with every variation mentioned above and the one from the first comment.
There are no additional lines added to the urlpatterns, as I understand it adding to here would open access up to the public via url.
it should be:
template = loader.get_template("test/template.html")

Deliver images in Django from a different path than from its ImageField.url property

I'm porting a web app from PHP (Codeigniter) to Python (powered by Django.) I already migrated the database and am now using Django models. I populated the database with images using Django's ImageField field and the images are in its proper folders under MEDIA_ROOT.
I'm in development so I'm using Django's server to test the web app as I go and I can serve the images through image.url.
image.url serves the image from:
MEDIA_ROOT/folder/subfolder/numberImage_folder_subfolder.jpg
But I need it to be served from MEDIA_ROOT/numberImage_folder_subfolder.jpg.
In production I know I can serve the image using nginx's XSendFile or something like that. Django's server (runserver command) is very easy to use and gives me what I need at the moment. While in development, how can I deliver the image from the URL I require? Preferably using Django's server...
Any help will be so much appreciated.
I'm not entirely clear on what your URLs are and how they map to file paths (and don't have the reputation to ask for clarification yet). So correct me if I've understood it wrong.
But in the meantime, to rephrase the question slightly, I think you're saying that you have the files stored on disk in those subfolders like MEDIA_ROOT/folder/subfolder/numberImage_folder_subfolder.jpg, but when you actually want the URLs served, you don't want the folders in the URL, so the URL will have MEDIA_ROOT/numberImage_folder_subfolder.jpg? And only with the ./manage.py runserver?
Going ahead on those assumptions, we have two steps: map the URLs we want back to a file path, and then also make sure we're generating the URLs we want.
For the first, normally urls.py will have something like this to serve media files in development:
from django.conf.urls.static import static
if settings.DEBUG is True:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
which is basically adding url(r'^media/(?P<path>.*)$', django.views.static.serve) to your urlconf, where serve takes all paths below settings.MEDIA_URL and serves up the equivalent file under MEDIA_ROOT.
The simplest way to do this would be to create a custom function modelled on that same django.conf.urls.static which takes the path and adds the folders back in before passing it on to django.views.static.serve.
For the second, if you want the URLs generated from the ImageField.url to differ from the underlying file storage path, you'll need to have a custom ImageField subclass overriding the FileField.url property (or a custom Storage class that does a similar thing).
Like so:
class CustomURLImageField(django.forms.fields.ImageField):
def _get_url(self):
"""
Override the standard FileField.url property to mangle the URL from
MEDIA_ROOT/folder/subfolder/numberImage.jpg
to
MEDIA_ROOT/numberImage_folder_subfolder.jpg
"""
self._require_file()
#return self.storage.url(self.name)
path_components = self.name.split('/')
folder = path_components[-3]
subfolder = path_components[-2]
numberImage, ext = os.path.splitext(path_components[-1])
return '/{numberImage}_{folder}_{subfolder}{ext}'.format(**locals())
url = property(_get_url)
This will be likely true in production too... how are you generating your URLs?)

Django wrong precedence of templates?

It took me forever to find out why a template was not getting overridden, only to find that it seems Django simply does not use the correct precedence in overriding the templates.
The templates I'm trying to change are the ones for changing the user's password, which are loaded for the URL /accounts/password/change.
I have my modified templates in mysite/myapp/templates/registration; the system default templates are at /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/templates/registration. When templates are present in both these directories, Django uses the system (/Library) ones. Huh?
When I remove the templates in /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/contrib/admin/templates/registration
, the correct ones (i.e. mine, in mysite/myapp/templates/registration) are loaded.
How to fix this issue? That is, how to make Django load my overridden templates without having the delete the original templates found in the /Library?
you have to create an admin directory inside the templates dir in which you set the templates you want to override
In order to override one or more of them, first create an admin directory in your project’s templates directory. This can be any of the directories you specified in TEMPLATE_DIRS.
Read the Django doc here

Should I render every page through a view function?

I have a simple static page that displays some information about the website. should i render this page via a render_to_response() even though it is static or should i simply display it as a normal html file?
the only thing I am concerned about is adding excess load on the server.
If you are worrying about server load, you should set up a proxy like squid or varnish. The proxy can cache the static content so your server will only get a more one request every time the cache expires
You might want to check out Hyde, which uses Django and specializes in static content.
It doesn't sound like you're really talking about "static content" in the way Django developers usually do (Javascript, CSS, images, etc.).
You say you need Django templates, but imply the content on those pages doesn't need to be changed. This sounds like the perfect opportunity for the built-in Django TemplateView (example urls.py from the docs):
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^about/', TemplateView.as_view(template_name="about.html")),
)
As gnibbler says, if you're very worried about performance then some kind of cache — Django actually has caching built-in,
and you can enable it for specific views with the #cache_page decorator.

Using external URLs in Django's TEMPLATE_DIRS

Django's TEMPLATE_DIRS in Settings.py calls for unix style slashes.
Because of this, when I call
get_template('some/template.html')
in a view, the result always starts at the root, and results in a call to
/home/username/projectname/public/some/template.html
The problem is that I'd like to use templates hosted on an entirely different site. This works fine for other Settings.py fields (MEDIA_URL and STATIC_URL), where it will take an absolute http path with no objection.
Given an http path,
TEMPLATE_DIRS ('http://example.com/',)
in Settings.py will force
get_template('some/template.html')
in a view to try and find
/home/username/projectname/public/http://example.com/some/template.html
I've tried to circumvent this like so
TEMPLATE_DIRS ('../../../../http://example.com/',)
But it still forces a leading slash, so I get "/http://example.com", which is useless.
My questions:
Is there a way to trick this into pulling the template files from
another server?
Is that even feasible, given that the template files need to be
processed for the view?
Is it possible to create an alternate to 'django.template.loaders.filesystem.Loader' that doesn't call for unix style slashes?
You don't need to use the template directory is you dont want to. If you have a server that is serving template files, you can simply fetch them remotely using urllib2 and create and render the template with a context manually:
import urllib2
from django.template import Context, Template
tpl_html = urllib2.urlopen("http://mysite.com")
tpl = Template(tpl_html)
return tpl.render(Context({
'some_variable' : 'some_val',
})
If you are going to do this, you have to incorporate some caching, as for every request to using this template, you need to make an external request. Alternatively you could write this into a custom loader but it will suffer the same limitations.
You can't do this.
It has nothing to do with path names. It's just that the filesystem template loader needs to load things from the filesystem, hence the name.
This is completely different from the case of MEDIA_URL: that simply adds a path into your HTML, which your browser then loads. Django doesn't care where that file lives: although in fact the opposite applies, in that if you pass it a filepath that isn't a URL (ie served by a webserver somewhere), it simply won't work.
Now, you could write a template loader that gets its templates from another server. Template loaders are pluggable - you just need to put the name of your new loader in the TEMPLATE_LOADERS setting. The loader itself would need to use something like urllib.urlopen to get the template from the external server.
But think very carefully before you do this. This means that every single template request now requires a call to an external server before you can serve the page. In the typical case of a template that extends other templates and includes calls to included template tags, that might be five or ten calls. And, unlike media files, it can't be done in parallel: the page simply won't be served until the whole process is finished. This is likely to make your webserver very very slow.
I don't know why you think you need to do this. Templates are part of your application code, so they would normally live on the same server as your Python code. If you really have some reason to keep them externally, one solution might be to mount the external filesystem onto your webserver via something like sshfs. It's still likely to be very slow though. Think again.
No - it's not possible to trick it into pulling files from another server via http
Yes - you certainly could subclass django.template.loaders.filesystem.Loader (and by altering the load_template_source method appropriately) so that you could load templates via http
Once you had done 3 then the answer to 2 would be yes - it would be feasible - ultimately Django's template language doesn't care where it gets the file from, as long it's in the right format.
However, it seems like a very inefficient way of loading templates and more likely there is a much better way of achieving the same result.

Categories

Resources