Dajaxice network error 404: method not found - django

I'm trying to create a basic submit form (like the dajaxice's example) but i keep receiving a 404 error from firebug console:
404 NOT FOUND 386ms
"NetworkError: 404 NOT FOUND - http://<my_website>/dajaxice/maynard.maynard_core.subscribe/"
My project folder structure is
/maynard/maynard_core/
This folder contains the main files of the project (views.py, ajax.py etc etc... main django project folder)
Inside the ajax.py file, there's the subscribe method:
from dajax.core import Dajax
from dajaxice.core import dajaxice_functions
from dajaxice.decorators import dajaxice_register
from views import subscribe_search
from forms import SubscriptionForm, SendMailForm
from django.core.mail import send_mail
def subscribe(request, form):
if request.POST:
dajax = Dajax()
form = SubscriptionForm(form)
try:
if form.is_valid():
url = form.cleaned_data['url_sub']
what = form.cleaned_data['what_sub']
where = form.cleaned_data['where_sub']
mail = form.cleaned_data['email']
subscribe_search(url,what,where,mail)
dajax.assign('#sub_mess_top','innerHTML','Thank you for subscribing to the search')
else:
dajax.add_css_class('#sub_mess_top','text error-message')
dajax.assign('#sub_mess_top','innerHTML','Couldn\'t complete the request, try again!')
return dajax.json()
except:
dajax.add_css_class('#sub_mess_top','text warning-message')
dajax.assign('#sub_mess_top','innerHTML','You already saved this search')
return dajax.json()
dajaxice_functions.register(subscribe)
Which is then called via this js method
function send_form_top(){
data = $('#subscribe').serializeObject(true);
Dajaxice.maynard.maynard_core.subscribe(Dajax.process,{'form':data});
}
The form is a basic form with action "#" and onclick="send_form_top();"
I followed the installation and configuration guide (settings configured, urls configured etc etc etc), and it's a very 101 implementation.
in urls.py
from dajaxice.core import dajaxice_autodiscover
dajaxice_autodiscover()
...
django.conf.urls.defaults.url(r'^%s/' % settings.DAJAXICE_MEDIA_PREFIX, django.conf.urls.defaults.include('dajaxice.urls')),
I added 'dajaxice' to my installed apps in settings.py, and DAJAXICE_MEDIA_PREFIX is 'dajaxice' (as in the docs).
Templates are fine too (since i have the dajaxice dynamically compiled js included)
But still i can't seem to be able to make it work. I checked throu the response headers, and this is what i get for the dajax.js file:
maynard_core: {
subscribe: function(callback_function, argv, custom_settings){
Dajaxice.call('maynard.maynard_core.subscribe', callback_function, argv, custom_settings);
},
...
This tells me that the submit method, which is in the ajax.py file inside maynard/maynard_core/ is actually included and the callback is correct too. I really don't know how to debug this any more, django logs shows nothing about it. Thanks all in advance, i'm really loosing my hair on this.

If you got a 404 error, definitely the problem is in your urls.py configuration.
There is any wildcard url above the dajaxice one? Try to put the dajaxice url conf on the beginning and see what happens.
Anyway... are your views.py, ajax.py, etc... inside any app? or all of them are in the root project folder. That could be the problem too.

Related

angular django rewrite unmatched urls to index.html (angular app)

I have a django server and an angular app.
I am able to launch the angular app and navigate to the various parts of the site using links i have added to the app.
But if I want to go to a part of the site directly I get a 404 error.
example if I have a link in my app that directs me to
niftysite.com/team
it works
but if I put in my browsers url
niftysite.com/team
it fails with 404
I understand this is because the default behavior is to look for the link to the page in the servers urls.
I also understand that the fix is to have server side 404s redirect to the angular index.html page with the route params included.
My question is how?
I have already started on an implementation but I am not sure how to fix it. Any guidance the rest of the way through would be helpful.
here is what I have so far.
urls.py
handler404 = views.error_404
views.py
from django.shortcuts import render
def error_404(request):
data = {}
return render(request, 'index.html', data)
similar to this question, but I am not using Nginx
How to redirect 404 requests to homepage in Django single page app using Nginx?
Here is the implementation:
urls.py
url(r'^.*$', views.PassToAngular.as_view())
make sure this url is the last url in your urls array.
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
class PassToAngular(TemplateView):
def get(self, request, **kwargs):
return render(request, 'index.html', context= None)
thanks to MihirKavatkar for your help!

Custom Error Pages for django-cms

Supposedly a trivial task to server 403/404/500 error pages when using django-cms. Followed instructions on an old forum post to create this:
from cms.views import details
def custom_404(request):
response = details(request, 'page-not-found')
response.status_code = 404
return response
...
Urls.py has some lines like this:
handler404 = 'error_pages.views.custom_404'
...
From traceback django cms can't locate 404 page:
File "/home/username/.virtualenvs/venv/lib/python2.7/site-packages/cms/views.py", line 22, in _handle_no_page
raise Http404('CMS: Page not found for "%s"' % slug)
Http404: CMS: Page not found for "page-not-found"
Obviously added the required custom pages in django-cms with the slug: 'page-not-found'. Am I missing something obvious? Running on production server with debug=False. Running django-cms 2.4.2 (edit)
Perhaps it is better to just serve plain ol' error messages with hardcoded stylesheets?
After walking into countless walls over-thinking the issues, I just went with using the basic 403/404/500 handlers:
from django.utils.functional import curry
from django.views.defaults import *
handler500 = curry(server_error, template_name='500.html')
handler404 = curry(page_not_found, template_name='404.html')
handler403 = curry(permission_denied, template_name='403.html')
Created the templates for each error and put in absolute URLs for the stylesheets.
Problem solved. Wasted a bunch of time on something this trivial.
Here is a working (with DEBUG at True or False) 404 handler:
def handler404(request):
if hasattr(request, '_current_page_cache'):
delattr(request, '_current_page_cache')
response = details(request, '404')
response.status_code = 404
return response
EDIT / Easy solution
After more searching and thinking, an easier solution would be to create the default/standard 404.html, and therein use django-cms static placeholders...as easy as it gets!
Original (still working) Answer
After struggling updating my handler404 from an old cms project, and not finding any infos on this topic, and the accepted answer not being a real solution to the problem, I investigated and found a version that works in django-cms 3.4.
Worth noting
delete the _current_page_cache on the request
set request.current_page, or cms_tags will not use your 404 page and render empty
call the main cms details view for rendering the page
finally, call response.render() (as mentioned in comments)
The view
def handler404(request):
if hasattr(request, '_current_page_cache'): # we'll hit the cache otherwise
delattr(request, '_current_page_cache')
page = get_page_from_request(request, '404')
request.current_page = page # templatags seem to use this.
response = details(request, '404') # the main cms view
if hasattr(response, 'render'): # 301/302 dont have it!
response.render() # didnt know about this, but it's needed
response.status_code = 404 # the obvious
return response

Custom Django 404 page and Django debug page

I am deploying a Django webpage and I love the Django Debug 404 page and and the Django page when there is a python error. However these aren't appropriate for a webpage that is going online. So I have made a custom 404 page. However, for me, and my IP address, I want to still have the Django Debug pages come up. Is there anyway to do this if I set Debug to false?
You can define your own handler-view for 404s, by setting handler404 in your urlconf. The default handler404 is django.views.defaults.page_not_found, which basically just renders the 404.html template.
If you put this in your urlconf, it will show the "technical" 404 response (the nice yellow page) for a certain IP, and use Django's default 404-production view for other IPs:
import sys
from django.views.debug import technical_404_response
from django.views.defaults import page_not_found
def handler404(request):
if request.META['REMOTE_ADDR'] == 'YOUR_IP_ADDRESS':
exc_type, exc_value, tb = sys.exc_info()
return technical_404_response(request, exc_value)
else:
return page_not_found(request)
I would advise you to set up proper logging for you 404 errors. Django can e-mail or log 404s and exceptions for you that happens in your production environment for rules that you can specify.
See the documentation on error reporting and logging (The logging framework was added in 1.3)

Django hostname middleware gets cached

I created a Django project to manage two separate sites that share some backend code. Both of the sites are inside separate apps. Each app has its own models.py, views.py, templates etc...
To be able to react differently to different hostnames, I created an URLconf middleware:
class HostnameBasedUrlconfMiddleware(object):
"""This middleware parses the hostname from the request, and selects the
urlconf accordingly.
To set a custom urlconf according to the current hostname, add an URLCONF
dictionary to your settings.py file.
URLCONF = {
'example.com': 'urls_example',
'example.dev': 'urls_dev',
'admin.example.dev': 'apps.admin.urls'
}
If the hostname is not found in the URLCONF dictionary, the default
ROOT_URLCONF setting will be used.
"""
def process_request(self, request):
# Decide which urlconf to use. Fallback is to use the ROOT_URLCONF
# as defined in the settings.py file.
try:
hostname = request.META['HTTP_HOST']
request.urlconf = settings.URLCONF[hostname]
except (KeyError, AttributeError):
pass
return None
This seemed to work at first, but then I became aware that some kind of caching must be happening.
When starting the server and requesting site A, it would show up. If I then request site B, site A shows up. Sometimes (but not always), after several reloads, site B would finally show up. After restarting the server and requesting site B, it would show up, but now site A would show site B content.
This happened with the builtin devserver as well as with gunicorn.
I tried to request the site with curl to avoid browser caching, no difference.
I also suspected it could be some kind of template name collision, but all templates are inside a uniquely named subfolder inside their respective template folders.
I don't have memcached installed and I'm not using any caching middleware.
What could be the problem? Is there some internal automatic caching going on?
Here is the code in question that substitutes in the urlconf (for 1.3 at least):
django.core.handlers.base:
class BaseHandler(object):
[...snip...]
def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest"
from django.core import exceptions, urlresolvers
from django.conf import settings
try:
# Setup default url resolver for this thread, this code is outside
# the try/except so we don't get a spurious "unbound local
# variable" exception in the event an exception is raised before
# resolver is set
urlconf = settings.ROOT_URLCONF
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
try:
response = None
# Apply request middleware
for middleware_method in self._request_middleware:
response = middleware_method(request)
if response:
break
if response is None:
if hasattr(request, "urlconf"):
# Reset url resolver with a custom urlconf.
urlconf = request.urlconf
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
[...snip...]
So, it looks like it's just using the value directly from request.urlconf. And your middleware is setting the request value directly.
I'd install django-debug-toolbar to confirm whether or not the value for request.urlconf is a) being set or b) being changed along the way.
To make absolutely sure, why not change the code temporarily to something like:
request.urlconf = settings.URLCONF[hostname]
request.urlconf_set = datetime.datetime.now()
Then you can look at the values in the debug toolbar (or just output them in a template) to see what might be going on.
However, I would suggest instead of using middleware, that you simply set up different settings.py files for each domain. Then, in whatever web server you're using, set each one up to use its own .wsgi file, which points to its own settings file, like so:
settings_a.py:
from settings import *
ROOT_URLCONF = 'urls_a.py'
settings_b.py
from settings import *
ROOT_URLCONF = 'urls_b.py'

Django flatpages raising 404 when DEBUG is False (404 and 500 templates exist)

I'm using Django 1.1.1 stable. When DEBUG is set to True Django flatpages works correctly; when DEBUG is False every flatpage I try to access raises a custom 404 error (my error template is obviously working correctly).
Searching around on the internet suggests creating 404 and 500 templates which I have done.
I've added to FlatpageFallBackMiddleware to middleware_classes and flatpages is added to installed applications. Any ideas how I can make flatpages work?
The same happened to me until I found that the 404 view was sending a 200 status response. So all you have to do is add this in the view that handles your 404 response:
def 404_handler(request): ...
response = render_to_response('404.html', locals(), context_instance=RequestContext(request))
response.status_code = 404
return response
try to add FlatpageFallBackMiddleware before django.middleware.common.CommonMiddleware
and be sure, that your 404.html and 500.html are stored in the root of your templates dir (eg: templates/404.html)
The key is checking the order of your middleware. Middleware is executed in top-down order on the way in (request and view) and in bottom-out order on the way out (response and exception). So if you are getting to your 404 handler on what should be a perfectly reasonable flatpage URL then something is catching the 404 before the flatpages middleware is getting called.
Had the same error in a different context. The problem was caused by me changing file urls.py from
from django.conf.urls.defaults import *
to
from django.conf.urls.defaults import include, patterns
as suggested by pylint, but this omits handler404 and handler500 which are expected to be imported implicitly by import *.
so either adding those to import or just importing * as django documents suggest solved the issue.
Make an error handling view that prints a stacktrace import traceback;traceback.print_exc() instead of ignoring the error silently.