Force django cache updating - python

I have a site with pages hierarchy, which shows tables based on complex calculation from values stored in database. That database can be updated by external application. During to long time of calculation, I prefer to use per-page caching to show result pages (I'm using DatabaseCache). After external updating of database, I can clear cache, but I want to refresh it (create new one instead) before user's visit (assuming that user will see only next cached version).
Is any way in Django to force refreshing cache by external application?
Comes to mind only calling some Django code from external app, which will call all the pages urls one-by-one, after cache deleting..
Will be grateful for your advice anyway

in your external script you can do
import django
from django.core.cache import cache
django.setup() # Needed to make django ready from the external script
cache.clear() # Flush all the old cache entry.

Related

Does python with wsgi (uwsgi) under nginx have some small default cache?

In my small web-site I feel need to make some data widely available, to avoid exchanging with database for every request made. E.g. this could be the list of current users show in the bottom of every page or the time of last update of ranking.
The stuff works in Python (Flask) running upon nginx + uwsgi (this docker image).
I wonder, do I have some small cache or shared memory for keeping such information "out of the box", or I need to take care of explicitly setting up some dedicated cache? Or perhaps some thing like this is provided by nginx?
alternatively I still can use database for it has its own cache I think, anyway
Sorry if question seems to be naive/silly - for I come from java world (where things a bit different as we serve all requests with one fat instance of java application) - and have some difficulty grasping what powers does wsgi/uwsgi provide. Thanks in advance!
Firstly, nginx has cache:
https://www.nginx.com/blog/nginx-caching-guide/
But for flask cacheing you also have options:
https://pythonhosted.org/Flask-Cache/
http://flask.pocoo.org/docs/1.0/patterns/caching/
Did you have a look at caching section from Flask docs?
It literally says:
Flask itself does not provide caching for you, but Werkzeug, one of the libraries it is based on, has some very basic cache support
You create a cache object once and keep it around, similar to how Flask objects are created. If you are using the development server you can create a SimpleCache object, that one is a simple cache that keeps the item stored in the memory of the Python interpreter:
from werkzeug.contrib.cache import SimpleCache
cache = SimpleCache()
-- UPDATE --
Or you could solve on the frontend side storing data in the web browser local storage.
If there's nothing in the local storage you call the DB, else you use the information from local storage rather than making db call.
Hope it helps.

Clearing sessions in django_session table without logging out current users

I am working on sessions in Django.
By default, django stores sessions in django_session, I found out there is no way to purge sessions.
Though clearsessions can be used to delete rows. It is also recommended to run this as a cron job. But doing this means logging out all logged-in users, right?
Is this the right way to do it?
The Django documentation states (emphasis from me):
Clearing the session store
As users create new sessions on your website, session data can
accumulate in your session store. If you’re using the database
backend, the django_session database table will grow. If you’re using
the file backend, your temporary directory will contain an increasing
number of files.
To understand this problem, consider what happens with the database
backend. When a user logs in, Django adds a row to the django_session
database table. Django updates this row each time the session data
changes. If the user logs out manually, Django deletes the row. But if
the user does not log out, the row never gets deleted. A similar
process happens with the file backend.
Django does not provide automatic purging of expired sessions.
Therefore, it’s your job to purge expired sessions on a regular basis.
Django provides a clean-up management command for this purpose:
clearsessions. It’s recommended to call this command on a regular
basis, for example as a daily cron job.
Note that the cache backend isn’t vulnerable to this problem, because
caches automatically delete stale data. Neither is the cookie backend,
because the session data is stored by the users’ browsers.
Found this link in Abid A's answer.
The clearsessions command
Can be run as a cron job or directly to clean out expired sessions.
So it won't log off every user.
As mentioned by Kevin Christopher Henry in a comment and in the other possible duplicate of your question flagged by e4c5.
Django 1.6 or Above
python manage.py clearsessions
Django 1.5 or lower
python manage.py cleanup
From Django Shell
from django.contrib.sessions.models import Session
Session.objects.all().delete()
django-session-cleanup
cronJob
clearing session in logout( based on session key present in request)
from django.contrib.sessions.models import Session
session_key = request.data['sessionKey']
session = Session.objects.get(session_key=session_key)
Session.objects.filter(session_key=session).delete()
Session.objects.all().delete()
The newer versions of Django allow:
request.session.clear()

Django sessions - keeping the session data between login/logout

I've been working on a small project and I've started wondering how to keep some data after the user logs in or logs out.
For example let's say that the user is adding items to his shopping cart and he is not logged in. Django sessions by default generate new session_id after the user logs in or logs out.
When the user adds 5 products to his cart when and he logs in afterwards then his cart will be cleared.
How to implement an element of persistence in user data? For example should I use some signals or some sort of middleware to bind the cart from old to new session?
My main goal is to keep it safe so I don't want to disable some security mechanisms.
You have to use the database-backed session. From the doc:
you need to add 'django.contrib.sessions' to your INSTALLED_APPS
setting.
Once you have configured your installation, run manage.py migrate to install the single database table that stores session data.
Then you have to ensure that the session.flush() is not called in the logout/login process, witch implies avoid using the django.contrib.auth.logout() witch will call session.flush(), it is also called in django.contrib.login(). login and logout the user yourself to avoid losing the session data. source for login/logout.
The session is flushed at login/logout, as a security measure. If you want to retain some variables, you can use the solution at:
https://stackoverflow.com/a/41849076/146289
It basically involves backing up old values, and then restoring them in the new session.

Storing session data in database in Pyramid using beaker

I'm building a web application in Pyramid and it needs user logins. Database backend is a MySQL DB connected via SQLAalchemy.
Pyramid has an introduction on using beaker for sessions, but it only shows how to configure it using files. I couldn't find out how to store session data in the database (I think it should be possible), since then I would have only one place were my varying data is stored.
I found it. Put something like this in your configuration file (development.ini/production.ini)
session.type=ext:database
session.secret=someThingReallyReallySecret
session.cookie_expires=true
session.key=WhatEver
session.url=mysql://user:password#host/database
session.timeout=3000
session.lock_dir=%(here)s/var/lock
I don't is if it is possible (or sensible) to put locking to the DB, too, but the sessions should live in the DB like this. You'll need to take care to delete old sessions from the DB yourself (but I think that's the case when using files, too).

How to Disable Django / mod_WSGI Page Caching

I have Django running in Apache via mod_wsgi. I believe Django is caching my pages server-side, which is causing some of the functionality to not work correctly.
I have a countdown timer that works by getting the current server time, determining the remaining countdown time, and outputting that number to the HTML template. A javascript countdown timer then takes over and runs the countdown for the user.
The problem arises when the user refreshes the page, or navigates to a different page with the countdown timer. The timer appears to jump around to different times sporadically, usually going back to the same time over and over again on each refresh.
Using HTTPFox, the page is not being loaded from my browser cache, so it looks like either Django or Apache is caching the page. Is there any way to disable this functionality? I'm not going to have enough traffic to worry about caching the script output. Or am I completely wrong about why this is happening?
[Edit] From the posts below, it looks like caching is disabled in Django, which means it must be happening elsewhere, perhaps in Apache?
[Edit] I have a more thorough description of what is happening: For the first 7 (or so) requests made to the server, the pages are rendered by the script and returned, although each of those 7 pages seems to be cached as it shows up later. On the 8th request, the server serves up the first page. On the 9th request, it serves up the second page, and so on in a cycle. This lasts until I restart apache, when the process starts over again.
[Edit] I have configured mod_wsgi to run only one process at a time, which causes the timer to reset to the same value in every case. Interestingly though, there's another component on my page that displays a random image on each request, using order('?'), and that does refresh with different images each time, which would indicate the caching is happening in Django and not in Apache.
[Edit] In light of the previous edit, I went back and reviewed the relevant views.py file, finding that the countdown start variable was being set globally in the module, outside of the view functions. Moving that setting inside the view functions resolved the problem. So it turned out not to be a caching issue after all. Thanks everyone for your help on this.
From my experience with mod_wsgi in Apache, it is highly unlikely that they are causing caching. A couple of things to try:
It is possible that you have some proxy server between your computer and the web server that is appropriately or inappropriately caching pages. Sometimes ISPs run proxy servers to reduce bandwidth outside their network. Can you please provide the HTTP headers for a page that is getting cached (Firebug can give these to you). Headers that I would specifically be interested in include Cache-Control, Expires, Last-Modified, and ETag.
Can you post your MIDDLEWARE_CLASSES from your settings.py file. It possible that you have a Middleware that performs caching for you.
Can you grep your code for the following items "load cache", "django.core.cache", and "cache_page". A *grep -R "search" ** will work.
Does the settings.py (or anything it imports like "from localsettings import *") include CACHE_BACKEND?
What happens when you restart apache? (e.g. sudo services apache restart). If a restart clears the issue, then it might be apache doing caching (it is possible that this could also clear out a locmen Django cache backend)
Did you specifically setup Django caching? From the docs it seems you would clearly know if Django was caching as it requires work beforehand to get it working. Specifically, you need to define where the cached files are saved.
http://docs.djangoproject.com/en/dev/topics/cache/
Are you using a multiprocess configuration for Apache/mod_wsgi? If you are, that will account for why different responses can have a different value for the timer as likely that when timer is initialised will be different for each process handling requests. Thus why it can jump around.
Have a read of:
http://code.google.com/p/modwsgi/wiki/ProcessesAndThreading
Work out in what mode or configuration you are running Apache/mod_wsgi and perhaps post what that configuration is. Without knowing, there are too many unknowns.
I just came across this:
Support for Automatic Reloading To help deployment tools you can
activate support for automatic reloading. Whenever something changes
the .wsgi file, mod_wsgi will reload all the daemon processes for us.
For that, just add the following directive to your Directory section:
WSGIScriptReloading On

Categories