Django caching useless with CSRF protection?

Hi, my site has a searchbox on each page, so I placed a {% csrf_token %} tag in the base template. Activating a per-site cache (or a per-view cache with the @cache_page and @csrf_protect decorators) does not affect the site’s performance at all, as the pages change with each request, so nothing is ever cached. Am I right, or is there some magical way around this (other than template fragment caching)?

I believe you are correct.

That doesn’t mean there aren’t possible work-arounds. I can think of two right off-hand.

  • URL-encode the contents of the searchbox, and submit it as a GET instead of a POST
  • If the view invoked by the searchbox is truly safe, mark that view as csrf_exempt
1 Like

Thank you! I am not confident that my search view (s. below) is truly safe, and am sufficiently terrified by CSRF prevention recommendations like this to avoid workarounds. I have tested template fragment caching successfully, although this approach does not leverage browser caching.

def search(request):
	if request.method == 'POST':
		form = SearchForm(request.POST)
		if form.is_valid():
			results = Page.objects.filter(title__icontains=form.cleaned_data['page_title'], content__icontains=form.cleaned_data['page_content'], author__last_name__icontains=form.cleaned_data['page_author']).order_by('title')
			return render(request, 'results.html', { 'results' : results,} )
	else:
		form = SearchForm()
	return render(request, 'form.html',
		{
			'target' : reverse(search),
			'form' : form,
		})

PS. You are one of the most friendly and competent people I met in any technical forum. Thanks for your time and patience.

A search would be “safe” in this context if there is no data being written. (No objects being created or updated, and no “user status” change such as a login/logout.)

I would have the opinion that this view would be considered safe.

1 Like