How do I disable Django per-view caching when debug is on? - django

I've written a bunch of views in Django that use per-page caching. The code looks like this:
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
#cache_page(60 * 5)
def view_page(request):
return HttpResponse('hello world')
This works wonderfully, but is a pain during testing. How do I only do caching with debug off?

Check out django's dummy cache backend.
So for your development enviroment you should set your cache backend to django.core.cache.backends.dummy.DummyCache

You could conditionally decorate your view.
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
from django.conf import settings
def view_page(request):
return HttpResponse('hello world')
if not settings.DEBUG:
view_page = cache_page(60 * 5)(view_page)
or perhaps this would work.
from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache
from django.conf import settings
production_cache = lambda func: cache_page(60 * 5)(func) if settings.DEBUG else never_cache(func)
#production_cache
def view_page(request):
return HttpResponse('hello world')
In fact it can be done without a lambda
from django.http import HttpResponse
from django.views.decorators.cache import cache_page, never_cache
from django.conf import settings
production_cache = cache_page(60 * 5) if not settings.DEBUG else never_cache
#production_cache
def view_page(request):
return HttpResponse('hello world')

Using #StephenPaulger's method, it will also prevent Django from setting the cache related headers like Expires. If you're working with another system that interprets these headers and keeps it's own cache as long as the date in the Expires header isn't reached, this can be pretty annoying while developing.
If you use never_cache, Django will set the Expires header to the current time of the request, so the document would be outdated right away.
You can create this in a separate file in your project:
from django.conf import settings
from django.views.decorators.cache import (
cache_page as django_cache_page, never_cache
)
if settings.DEBUG:
cache_func = lambda seconds: never_cache
else:
cache_func = django_cache_page
def cache_page(seconds):
return cache_func(seconds)
Then you can import this custom cache_page function instead of the native Django one and use it the same way. This if statement would only be executed once when the module is imported.
If you have separate settings files (for development and production) you can even make it more efficient by putting the functions in the settings files. So for the development settings you would do this:
from django.views.decorators.cache import never_cache
CACHE_FUNC = lambda seconds: never_cache
And in the production settings you would put:
from django.views.decorators.cache import cache_page
CACHE_FUNC = cache_page
Then in a separate file in your project:
from django.conf import settings
def cache_page(seconds):
return settings.CACHE_FUNC(seconds)
With this method, the CACHE_FUNC would be defined only once during the startup of Django. So no impact on performance, and no annoying Expires headers during development!

Related

Django dev server using old version of views.py

For some reason, the changes I make on the views.py file are not being reflected. I initially made a function inside view.py to return HttpResponse(request.POST.items()). Even after making changes to the function, it's still performing the same thing. I tried clearing the cache of the browser, restarted the server, and also tried deleting the pyc files. Nothing worked. Any guess on why this is happening?
urls.py
from . import views
urlpatterns = [
path('',views.index, name='index'),
path('proceedaction/<str:pk>/',views.ProceedAction.as_view(),name='proceedaction'),
path('uploadct/<str:pk>/',views.UploadCT.as_view(),name='uploadct'),
]
views.py
from django.shortcuts import render,redirect
from django.views import View
from .models import CreatePatient,PatientRecord,FileData
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from .filters import RecordFilter
from django.http import HttpResponse
import json
# Create your views here.
def index(request):
return render(request,'index.html')
class UploadCT(View,LoginRequiredMixin):
def get(self,request,pk):
records = PatientRecord.objects.filter(id=pk)
context={
'record' : records,
}
return render(request,'ct_upload.html',context=context)
def post(self,request):
dbdata = FileData()
return redirect('index')
I had not specified method=POST in the corresponding HTML file. Solved this issue by doing that.

ImportError: cannot import name views while running the server

I am getting following error and donĀ“t know how to solve this:
from . import views
ImportError: cannot import name views
This are my scripts i am using:
urls.py
from django.conf.urls import url
from django.contrib import admin
from . import views
urlpatterns = [
url(r'^$',views.home,name='index'),
url(r'^admin/', admin.site.urls),]
views.py
from __future__ import unicode_literals
from django.http import HttpResponse
def index(request):
return HttpResponse("libaray management system")
Try to import like this
from your_app_name import views
I can't say, what is your project structure and where are your views.py and urls.py files. My guess, that you have some problems with how you import (check the absolute and relative import in python). In that case you can use import style from above code example.

ImportError: cannot import name Upload

I am working on Django, django-rest project and as I have searched the problem, it is beleived I have circular problem, but I don`t think so...
Relevant parts of problem are here:
demo/views.py
from django.shortcuts import render
from rest_auth.models import Upload, UploadForm
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
# Create your views here.
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
img.save()
return HttpResponseRedirect(reverse('imageupload'))
else:
img=UploadForm()
images=Upload.objects.all()
return render(request,'home.html',{'form':img,'images':images})
rest_auth/models.py
from django.conf import settings
from rest_framework.authtoken.models import Token as DefaultTokenModel
from .utils import import_callable
from django.db import models
from django.forms import ModelForm
class Upload(models.Model):
pic = models.ImageField("Image", upload_to="images/")
upload_date=models.DateTimeField(auto_now_add =True)
# FileUpload form class.
class UploadForm(ModelForm):
class Meta:
model = Upload
and
demo/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.views.generic import TemplateView, RedirectView
from django.conf import settings
from django.conf.urls.static import static
from views import home
from rest_framework_swagger.views import get_swagger_view
import os
PROJECT_DIR=os.path.dirname(__file__)
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name="home.html"), name='home'),
url(r'^upload/$', views.home, name='imageupload'),
url(r'^signup/$', TemplateView.as_view(template_name="signup.html"),
name='signup'),
Problem is as stated this:
File "/Desktop/zadnja/django-rest-auth/demo/demo/urls.py",
line 6, in
from views import home File "/Desktop/zadnja/django-rest-auth/demo/demo/views.py", line
2, in
from rest_auth.models import Upload, UploadForm ImportError: cannot import name Upload
You do not have circular imports since rest_auth/models.py does not import any component from demo/views.py
I'm assuming rest_auth is an app in you project. To import Upload and UploadForm you should use absolute import:
from project_name.rest_auth.models import Upload, UploadForm

Django cross site ajax(get) not getting response

I need to get the userid of user logged in to my django site. I am using Django 1.3.1.
Template
$.get(http://www.tomjoyapp.com/pinTag/, { URL: document.URL},
function(data){
alert("Data Loaded: " + data.responseText);
});
view
import os
from django.template.loader import get_template
from django.http import HttpResponse,HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import Context, RequestContext
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def pinTag(request):
user=request.user.id
return HttpResponse(str(user))
I need to get the userid as response if he is logged in to my django app.
I am getting the status as 200 OK. But No response.

Following django form submission, redirect to page using newly created pk

I am trying to redirect the user to edit details of a task after task submission, but am having troubles redirecting to a page based on the newly created pk. Each view works without the return HttpResponseRedirect line. I have also tried arge=(instance.id) and kwargs=(instance.id) for the variable.
views.py
...
from django.http import HttpResponseRedirect, HttpResponseServerError, HttpResponseForbidden, Http404, HttpResponse
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response, get_object_or_404,render
...
def new_task(request):
...
...
task.save()
instance = task.save()
return HttpResponseRedirect(reverse('task_values', instance.id))
def task_values(request, task_id):
...
urls.py
from django.conf.urls.defaults import patterns, include, url
from django.http import HttpResponseRedirect
from django.views.generic.simple import direct_to_template
urlpatterns += patterns('core.views_entry',
#Task viewing/editing
(r'^task/(?P<task_id>\d+)/$','task_values'),
(r'^enter/$','new_task'),
return HttpResponseRedirect(reverse('task_values', kwargs={'task_id': instance.id}))
Also note that you don't need to save the task twice.
Edit OK, there's another problem. You haven't given your URLs specific names, which means that the only way to identify them is to pass the fully qualified view name:
reverse('core.views_entry.task_values', kwargs=...)
Or, better, use the the url() function to name your URL:
url(r'^task/(?P<task_id>\d+)/$','task_values', name='task_values'),
and you can use the original version I gave above.
Note that the error isn't telling you it's going to enter/<id>/, just that in that view it's trying to create the reverse URL for the redirection and failing.