We recently launched a new Django-powered website, and we are experiencing the oddest bug:
The site is running under Apache with mod_fastcgi. Everything works fine for a while, and then the URL tag and reverse() functionality stops working. Instead of returning the expected URL, they return "".
We haven't noticed anything in Apache's log file; there are no errors being generated by Django. And (the kicker) the problem only occurs in production mode; we can't reproduce it when DEBUG=True.
Any thoughts on where we should be looking for the problem?
Update: It turned out to be a problem with settings.LANGUAGES, although we haven't determined exactly why that broke things.
This has happened to me before. Normally it's due to a 'broken' urls.py file. There are two things that make this kind of bug really hard to fix:
It could be the urls.py file in any of the apps that breaks the reverse() function, so knowing that reverse() breaks for app X doesn't mean the error is in that particular application's urls.py.
Django won't even notify you of errors in the urls.py file, unless you somehow manage to crash the site by doing something really, really nasty in the urls.py file.
Debugging: The way I go around fixing this is by manually disabling all applications (just comment out their line in INSTALLED_APPS) and checking reverse() works. If it still works, then I enable the next app, until it breaks. I know, very rudimentary stuff, but it works :)
Django has a odd behaviour when matching urls in a environment that isn't under debug mode.
For example, with DEBUG=False, Django will ignore urls such as:
url(r'^', include('someapp.urls')),
specifically in the case above, you could let the string empty:
url(r'', include('someapp.urls')),
In other words, check your regexes.
Can you put your urls.py here to be analyzed?
Related
This is a more-general question – just hoping to find someone who already knows.
("To save my forehead," y'know.) ;-)
I want to use CKEditor in conjunction with Machina forums, and I specifically want to be able to "drag and drop" images. I've found the right CKEditor feature to do that, but I'm getting "Incorrect Server Response" messages from CKEditor when I try to accomplish the drop. (This also happens on my development box.)
(Note that my concern is quite-particular to Django ("django-ckeditor"), and to the Machina forum software ("django-machina"). I need answers that are very tightly focused upon this use-case.)
So is there anyone out there who might say – "oh yeah, that happened to me, too, and the way to fix it is ...?"
Well, what do you know? I figured it out.
The problem was – and, as the django-ckeditor documentation clearly states, the default urlpattern entries (in the include file) specify a "staff-only" decorator for uploads. So, ckeditor was getting an error-message response and of course it didn't know what to do.
To solve the problem:
First, of course, be sure that ckeditor_uploader (as well as ckeditor) is installed on your system and is in your INSTALLED_APPS list in settings.py.
Now, in your urls.py, first add this line near the top:
from ckeditor_uploader import views as uploader_views
Next, insert the urlpattern entries that you find in the package's urls.py file, but referencing the uploader_viewsalias, viz:
url(r'^ckeditor/upload/',
uploader_views.upload, name='ckeditor_upload'),
url(r'^ckeditor/browse/',
never_cache(uploader_views.browse), name='ckeditor_browse'),
If you erroneously attempt to specify ckeditor_uploader.views. in the url() entry, you will be rewarded with:
NameError: name 'ckeditor_uploader' is not defined
Now you know! :-)
Also, don't forget what the Machina documentation told you to remember: ;-)
MACHINA_MARKUP_WIDGET = 'ckeditor_uploader.widgets.CKEditorUploadingWidget'
If you're doing "drag and drop," you're necessarily doing "file uploads," so you must use the provided field-types or (equivalently ...) the provided widgets from the ckeditor_uploader app.
I was following Django tutorial, and got stuck where it asked me to replace the default template for administrative part of the site with my own. The problem was a typo in the template's name. I suspected there must be a problem like that, but to troubleshoot the problem it'd be very helpful to see some kind of report from Django on what template it used to render a particular page. Is there any way to do this?
First if you have set DEBUG = True django automatically gives you information about where django was looking for templates (in general and especially in case it didn't find one)
You should see something like this:
second you can add the popular django plugin django-debug-toolbar. It can show you for each request what templates were used and what their context was.
see: https://django-debug-toolbar.readthedocs.io/en/stable/panels.html#template
Still, not exactly the answer, but something to get me closer. One could start Django shell, and then try this:
>>> from django.template.loader import get_template
>>> get_template('template/name').origin.name
to find out what template was actually used. This is still not enough to see though which templates were considered while resolving the template.
Usually I have the opposite problem, Django can't find the templates.
Lastly, I change a template of mine called custmber_view.html, but Django didn't notice the chagnes.
I tried flushing all caches, without success. In my dispair, I completely removed the template
hoping to see the familiar TemplateDoesNotExist exception.
To my surprise, Django keeps rendering the template! Although it is not found on the hard-drive.
Can someone suggest a solution to this mystery?
ARGH, legacy projects, I am doomed to fix them for ever. Somewise guy put the following in settings.py:
TEMPLATE_DIRS = (
os.path.join(project_dir, u'templates'),
u'/var/www/venv2.7/lib/python2.7/site-packages/backoffice/templates',
)
I feel like this now ...
So, conclusion, If you are working on a project which was not made as a Django App, always make sure you read the variable TEMPLATE_DIRS.
But for your colleagues future (and for better moral) always follow How to write reusable Django app
My project's URLs are automatically generated in urls.py using a for loop (the URLs look like AppName/ViewName). According to the docs, urls.py is loaded upon every request. This appears to be slowing my site down since it requires a bunch of introspection code, so I want to generate the URLs less frequently. I could of course manually run a script to re-generate urls.py (or a file imported by urls.py) as needed, but would prefer if it happened automatically as part of project validation/startup (like the server starting up or the database being synced). I'm open-sourcing this project, and many people will be running it on their own servers, so I want to do this in a robust way. Any recommendations?
The docs do not say what you claim they do (or rather, you're reading too much into a phrase which only means "loads that Python module (if it has not already been loaded)".
Generally, the only things that happen on every request are running the middleware and the specific view code associated with that request. Even then, nothing is reloaded on every request. URLs, like all Python code, is only loaded when a new process is started, and when that happens depends on your server setup. Your problem is elsewhere: you should profile your application carefully to find out exactly where.
For example you can look for django-json-rpc where author has realized url-generating via decorators. There are main controller which receive all requests and urls dict {'pattern': method}. urls dict filled automatically by decorators like #jsonrpc_method which receive a function and put them to urls.
I think it must run faster than the for and I believe that this approach will be able to apply for django.urls
This one has me scratching my head. I have an app with views that do form processing (logins/signup) and then return various HttpResponseRedirect()s based on the input. All of those redirects contain reverse() lookups with the appropriate functions listed as strings. And every function has a corresponding urlpattern in urls.py.
Everything was working fine until this morning.
Now, whenever I submit a form, Django gives me a syntax error for a non-existent line:
SyntaxError at /logout/
invalid syntax (views.py, line 399)
(That file only has 354 lines)
When I scroll down to look at the traceback, the line that's highlighted is always one with a return HttpResponseRedirect( reverse('app.views.func') ).
Because of these bewildering error messages, I'm not even sure that the problem is really with the HttpResponseRedirect( reverse() )s. I haven't touched any of that code in a few days, so I'm not sure why it would suddenly start throwing out weird errors like that.
Any help debugging this would be much appreciated!
I finally figured it out after consulting the docs for the reverse() function.
When you call reverse(), django first imports your project's URLConf files, which in turn imports every single view module that is declared in your URLconf. My issue was that I was working on a new, totally unrelated view that had a syntax error (on line 399!).
So even though I wasn't viewing a page that was doing anything with the new view, my old view was still getting tripped up with the syntax error because of how reverse() works.
From the docs:
Make sure your views are all correct. As part of working out which URL
names map to which patterns, the reverse() function has to import all
of your URLconf files and examine the name of each view. This involves
importing each view function. If there are any errors whilst importing
any of your view functions, it will cause reverse() to raise an error,
even if that view function is not the one you are trying to reverse.
Make sure that any views you reference in your URLconf files exist and
can be imported correctly. Do not include lines that reference views
you haven't written yet, because those views will not be importable.