cProfiler Django middleware: sorting the stats - django

In Django, I am using the below middleware Cprofiler snippet /from http://djangosnippets.org/snippets/727/ )
How do I change what is used to sort it? If I want to use sort_stats() where does that go in the code?
import sys
import cProfile
from cStringIO import StringIO
from django.conf import settings
class ProfilerMiddleware(object):
def process_view(self, request, callback, callback_args, callback_kwargs):
if settings.DEBUG and 'prof' in request.GET:
self.profiler = cProfile.Profile()
args = (request,) + callback_args
return self.profiler.runcall(callback, *args, **callback_kwargs)
def process_response(self, request, response):
if settings.DEBUG and 'prof' in request.GET:
self.profiler.create_stats()
out = StringIO()
old_stdout, sys.stdout = sys.stdout, out
self.profiler.print_stats(1)
sys.stdout = old_stdout
response.content = '<pre>%s</pre>' % out.getvalue()
return response

I think you are looking for the sort_stats function and it needs to go right before print_stats.
def process_response(self, request, response):
if settings.DEBUG and 'prof' in request.GET:
self.profiler.create_stats()
out = StringIO()
old_stdout, sys.stdout = sys.stdout, out
self.profiler.sort_stats('name')
self.profiler.print_stats(1)
sys.stdout = old_stdout
response.content = '<pre>%s</pre>' % out.getvalue()
return response
Also take a look at this http://docs.python.org/2/library/profile.html

sort_stats() cannot be used directly on the profiler. I found the solution here:
http://djangosnippets.org/snippets/1579/

Related

Django call function to save file cannot work

I am create Django project and create function for download file, But my project cannot work, File not response to save
view.py
from django.http.response import HttpResponse
from django.conf import settings
from django.http import HttpResponse, Http404
def index(request):
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
filename = 'my_file.json'
filepath = BASE_DIR + '/filedownload/' + filename
download(request,filepath)
return HttpResponse('Download File')
def download(request, path):
file_path = path
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/x-download")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404
How can I solve this?
Your download() returns response to your index() and your index() returns its own response(not a response of download()). If you returns response of download() like below, it will works.
import os
from django.http.response import HttpResponse
from django.conf import settings
from django.http import HttpResponse, Http404
def index(request):
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
filename = 'my_file.json'
filepath = BASE_DIR + '/filedownload/' + filename
return download(request,filepath)
def download(request, path):
file_path = path
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/x-download")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
raise Http404

Setting variable is not being set up during testing middleware (p

settings.py
MY_VAR = os.get("MY_VAR", False)
custom_middleware.py
from my_proj.settings import MY_VAR
from django.core.exceptions import MiddlewareNotUsed
class CustomMiddleware:
def _init_(self, get_response):
if MY_VAR == 'False':
raise MiddlewareNotUsed
self.get_response = get_response
def __call__(self, request):
if MY_VAR == 'True':
#My custom logic
return
response = self.get_response(request)
return response
test_custom_middleware.py
import os from unittest.mock import Mock
from api.middlewares.custom_middleware import CustomMiddleware
class TestLCustomMiddleware:
def test(self, settings):
request = Mock()
settings.MY_VAR = 'True'
assert settings.MY_VAR
with patch.dict('os.environ', {'MY_VAR': 'True'}):
assert 'MY_VAR' in os.environ
middleware = CustomMiddleware(get_response='response')
middleware(request)
In CustomMiddleware I always get "False" in MY_VAR variable of settings. How can I set it up?
Updated.
Thanks to Philippe and Dharman.
It works fine
custom_middleware.py
from django.conf import settings
from django.core.exceptions import MiddlewareNotUsed
class CustomMiddleware:
def _init_(self, get_response):
if settings.MY_VAR == 'False':
raise MiddlewareNotUsed
self.get_response = get_response
def __call__(self, request):
if settings.MY_VAR == 'True':
#My custom logic
return
response = self.get_response(request)
return response
test_custom_middleware.py
from api.middlewares.custom_middleware import CustomMiddleware
from django.test import override_settings
class TestLCustomMiddleware:
#override_settings(MY_VAR="True")
def test(self):
request = Mock()
middleware = CustomMiddleware(get_response='response')
middleware(request)
As explaned in Django documentation, you should import your setting using :
from django.conf import settings
if settings.MY_VAR:
# Do something
"django.conf.settings" isn’t a module, it’s an object. So importing individual settings is not possible. This example below won't work properly :
from django.conf.settings import MY_VAR
Furthermore, it's not recommended to change setting during Runtime :
from django.conf import settings
settings.DEBUG = True # Don't do this!
Instead you should try using override_settings() or modify_settings().
For example :
from django.test import TestCase, override_settings
class TestLCustomMiddleware(TestCase):
#override_settings(MY_VAR=True) # without quote
def test(self):
...

Django Middleware is not able to process view functions correctly

I am trying to do login/logout using Django Middleware. I have gone through few tutorials but all are posted with old versions. I am trying to hardcode the except function inside middleware instead of having in setting.py as follow:
middleware.py:
EXEMPT_FUNC = ['Accounts:login', 'Accounts:logout', 'Accounts:register']
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user')
path = request.path_info.lstrip('/')
url_is_exempt = any(url.match(path) for url in EXEMPT_FUNC)
if path == reverse('Accounts:logout').lstrip('/'):
logout(request)
if request.user.is_authenticated() and url_is_exempt:
return redirect('User:home')
elif request.user.is_authenticated() or url_is_exempt:
return None
else:
return redirect('Accounts:login')
url.py:
app_name = 'Accounts'
urlpatterns = [
path('login', views.login_view, name='login'),
path('logout', views.logout_view, name='logout'),
path('register', views.register_view, name='register')
]
Above code is not working as intended, please help on what am I doing wrong.
Really appreciate your help.
Finally its working.
Here is what I changed.
middleware.py:
import re
from django.conf import settings
from django.urls import reverse
from django.shortcuts import redirect
from django.contrib.auth import logout
from Accounts import views
EXEMPT_PATH = ['login', 'logout', 'register']
class LoginRequiredMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
return response
def process_view(self, request, view_func, view_args, view_kwargs):
assert hasattr(request, 'user')
path = request.path_info.lstrip('/')
exempt = False
if path in EXEMPT_PATH:
exempt = True
if path == 'logout':
logout(request)
if request.user.is_authenticated and exempt:
return redirect('User:home')
elif request.user.is_authenticated or exempt:
return None
else:
return redirect('Accounts:login')
With this approach I don't need to modify settings.py.
I hope this helps.

Django: NoReverseMatch Error production_id: None

Having an issue where I would fill out the form and when I click to save the input, it would show the info submitted into the query but my production_id value would return as None.
Here is the error:
Environment:
Request Method: POST
Request URL: http://192.168.33.10:8000/podfunnel/episodeinfo/
Django Version: 1.9
Python Version: 2.7.6
Installed Applications:
('producer',
'django.contrib.admin',
'django.contrib.sites',
'registration',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'storages',
'django_extensions',
'randomslugfield',
'adminsortable2',
'crispy_forms')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/contrib/auth/mixins.py" in dispatch
56. return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/home/vagrant/fullcast_project/producer/views/pod_funnel.py" in post
601. return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs={'production_id':production_id}))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in reverse
600. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py" in _reverse_with_prefix
508. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /podfunnel/episodeinfo/
Exception Value: Reverse for 'episodeimagefiles' with arguments '()' and keyword arguments '{'production_id': None}' not found. 1 pattern(s) tried: [u'podfunnel/episodeimagefiles/(?P<production_id>[0-9]+)/$']
Here is my pod_funnel.py view:
from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden
from django.shortcuts import render, get_object_or_404
from django.views.generic import View, RedirectView, TemplateView
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from .forms.client_setup import ClientSetupForm
from .forms.podcast_setup import PodcastSetupForm
from .forms.episode_info import EpisodeInfoForm
from .forms.image_files import EpisodeImageFilesForm
from .forms.wordpress_info import EpisodeWordpressInfoForm
from .forms.chapter_marks import EpisodeChapterMarksForm
from .forms.show_links import ShowLinksForm
from .forms.tweetables import TweetablesForm
from .forms.clicktotweet import ClickToTweetForm
from .forms.schedule import ScheduleForm
from .forms.wordpress_account import WordpressAccountForm
from .forms.wordpress_account_setup import WordpressAccountSetupForm
from .forms.wordpress_account_sortable import WordpressAccountSortableForm
from .forms.soundcloud_account import SoundcloudAccountForm
from .forms.twitter_account import TwitterAccountForm
from producer.helpers import get_podfunnel_client_and_podcast_for_user
from producer.helpers.soundcloud_api import SoundcloudAPI
from producer.helpers.twitter import TwitterAPI
from django.conf import settings
from producer.models import Client, Production, ChapterMark, ProductionLink, ProductionTweet, Podcast, WordpressConfig, Credentials, WordPressSortableSection, \
TwitterConfig, SoundcloudConfig
from django.core.urlresolvers import reverse
from producer.tasks.auphonic import update_or_create_preset_for_podcast
class EpisodeInfoView(LoginRequiredMixin, View):
form_class = EpisodeInfoForm
template_name = 'pod_funnel/forms_episode_info.html'
def get(self, request, *args, **kwargs):
initial_values = {}
user = request.user
# Lets get client and podcast for the user already. if not existent raise 404
client, podcast = get_podfunnel_client_and_podcast_for_user(user)
if client is None or podcast is None:
raise Http404
# See if a production_id is passed on the kwargs, if so, retrieve and fill current data.
# if not just provide empty form since will be new.
production_id = kwargs.get('production_id', None)
if production_id:
production = get_object_or_404(Production, id=production_id)
# Ensure this production belongs to this user, if not Unauthorized, 403
if production.podcast_id != podcast.id:
return HttpResponseForbidden()
initial_values['production_id'] = production.id
initial_values['episode_number'] = production.episode_number
initial_values['episode_title'] = production.episode_title
initial_values['episode_guest_first_name'] = production.episode_guest_first_name
initial_values['episode_guest_last_name'] = production.episode_guest_last_name
initial_values['episode_guest_twitter_name'] = production.episode_guest_twitter_name
initial_values['episode_summary'] = production.episode_summary
form = self.form_class(initial=initial_values)
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
client, podcast = get_podfunnel_client_and_podcast_for_user(request.user)
if form.is_valid():
# lets get the data
production_id = form.cleaned_data.get('production_id')
episode_number = form.cleaned_data.get('episode_number')
episode_title = form.cleaned_data.get('episode_title')
episode_guest_first_name = form.cleaned_data.get('episode_guest_first_name')
episode_guest_last_name = form.cleaned_data.get('episode_guest_last_name')
episode_guest_twitter_name = form.cleaned_data.get('episode_guest_twitter_name')
episode_summary = form.cleaned_data.get('episode_summary')
#if a production existed, we update, if not we create
if production_id is not None:
production = Production.objects.get(id=production_id)
else:
production = Production(podcast=podcast)
production.episode_number = episode_number
production.episode_title = episode_title
production.episode_guest_first_name = episode_guest_first_name
production.episode_guest_last_name = episode_guest_last_name
production.episode_guest_twitter_name = episode_guest_twitter_name
production.episode_summary = episode_summary
production.save()
return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs={'production_id':production_id}))
return render(request, self.template_name, {'form': form})
episode_info.py form:
from django import forms
class EpisodeInfoForm(forms.Form):
production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False)
episode_number = forms.IntegerField(widget=forms.NumberInput, required=True)
episode_title = forms.CharField(max_length=255, required=True)
episode_guest_first_name = forms.CharField(max_length=128)
episode_guest_last_name = forms.CharField(max_length=128)
episode_guest_twitter_name = forms.CharField(max_length=64)
episode_summary = forms.CharField(widget=forms.Textarea)
And url.py:
from django.conf.urls import url
from django.views.generic import TemplateView
import producer.views.pod_funnel as views
urlpatterns = [
url(r'^dashboard/', views.dashboard, name="dashboard"),
url(r'^clientsetup/', views.ClientSetupView.as_view(), name="clientsetup"),
url(r'^podcastsetup/', views.PodcastSetupView.as_view(), name="podcastsetup"),
url(r'^episodeinfo/$', views.EpisodeInfoView.as_view(), name="episodeinfo"),
url(r'^episodeinfo/(?P<production_id>[0-9]+)/$', views.EpisodeInfoView.as_view(), name="episodeinfo_edit"),
url(r'^episodeimagefiles/(?P<production_id>[0-9]+)/$', views.EpisodeImageFilesView.as_view(), name="episodeimagefiles"),
Any suggestion would be appreciated.
It looks like production_id can be None in your view, in which case you can't use it when you call reverse. It would be better to use production.id instead. You have just saved the production in your view, so production.id will be set.
return HttpResponseRedirect(reverse('podfunnel:episodeimagefiles', kwargs={'production_id':production.id}))
Note that you can simplify this line by using the redirect shortcut. Add the import,
from django.shortcuts import redirect
then change the line to
return redirect('podfunnel:episodeimagefiles', production_id=production.id)
You can't always redirect to episodeimagefiles if you didn't provide appropriate initial value for production_id:
# See if a production_id is passed on the kwargs, if so, retrieve and fill current data.
# if not just provide empty form since will be new.
production_id = kwargs.get('production_id', None) <-- here you set production_id variable to None if no `production_id` in kwargs
Look at your exception:
Exception Value: Reverse for 'episodeimagefiles' with arguments '()' and keyword arguments '{'production_id': None}' not found. 1 pattern(s) tried: [u'podfunnel/episodeimagefiles/(?P<production_id>[0-9]+)/$']
It means you passed None value for production_id variable, but episodeimagefiles pattern required some int value to resolve url, so it raises NoReverseMatch exception.
Your form is valid in EpisodeInfoView.post because you set required=False for production_id attribute in your form:
class EpisodeInfoForm(forms.Form):
production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False)
I guess, if you debug your generated form before submit it, you can see something like <input type="hidden" name="production_id" value="None" />

Clear Django cache for certain app or page

Is there any possibility to clear cache for certain app in django or for certain page?
I've tried to find it but in vain.
Thanks in advance.
Something like this might help you..
from django.core.cache import get_cache, DEFAULT_CACHE_ALIAS
from django.utils.cache import get_cache_key, _generate_cache_header_key, _generate_cache_key
from django.core.urlresolvers import reverse
from django.http import HttpRequest
from django.conf import settings
def expire_cache(path, args=[], cache_name=None, isview=True, lang_code=None, method='GET'):
if cache_name is None:
cache_name = DEFAULT_CACHE_ALIAS
cache = get_cache(cache_name)
key_prefix = settings.CACHES[cache_name].get('KEY_PREFIX', '')
request = HttpRequest()
if isview:
request.path = reverse(path, args=args)
else:
request.path = path
language_code = lang_code or getattr(settings, 'LANGUAGE_CODE')
if language_code:
request.LANGUAGE_CODE = language_code
header_key = _generate_cache_header_key(key_prefix, request)
if not header_key:
return False
headerlist = cache.get(header_key, None)
if headerlist is not None:
cache.set(header_key, None, 0)
page_key = _generate_cache_key(request, method, headerlist, key_prefix)
if not page_key:
return False
cache.set(page_key, None, 0)
return True
expire_cache('apps.yourapp.views.function')