Django 1.2 won't run my view - django

I'm getting a 404 from my Django server even though it's aware of my view code. If I purposely misspelled the name of the view function, Django complains, so I know it's looking in the right place and that it is aware of this function.
My urls.py entry looks like this
url(r"^pdfgen/$", 'apps.pdfgen.views.pdfgen'),
And my view code is this
def pdfgen(request):
html = "<html><body>This is a test.</body></html>"
return HttpResponse(html)
So why is it that Django 404's when I visit localhost:xxxx/pdfgen/ ?

If I purposely misspelled the name of the view function, Django complains, so I know it's looking in the right place and that it is aware of this function.
That doesn't mean that your request is hitting the correct view - it just means that Django can't load your url conf when you include views that don't exist. To be sure that Django is running the view you think it is, you need to add some logging or print statements to the view, or raise an exception in it.
Update your question to include all your url patterns. Your request is probably matching a view further up, which is returning the 404.

Related

Moved legacy classic asp web site to django app but having trouble with django URL redirect app - old URLs with parameters get 500 error

I moved a 20 year old classic asp web site to a django app recently. Google Search Console is showing 500 errors for tons of very old URLS with parameters like /somefile.asp?ID=1234&name=some-name. Most of these URLS I don't even care about - they are really old but would rather they result in 404 than 500. Some do relate to newer content and in theory I could redirect to new django pages but when I try to redirect them using the django redirect app, the site shows 500 errors - like the ? either stops the pages from ever getting to the redirect middleware or the redirect app doesn't like the "?". How can I redirect these urls so I don't get 500 errors? Is there a way in a view to say:
if the full url path is x
redirect to full url path y
I have looked all over stack overflow and elsewhere and can't find this exact problem or a way to write a view like this. I did try the solution here (exactly) because it seems closest to my issue, but it did not work for me for this exact problem: Django's redirects app doesn't work with URL parameters
An example would be /profiles/?adid=134&v=857
The error with debug true is:
DoesNotExist at /profiles/
BusinessCategory matching query does not exist....
So it is trying to match this URL:
path('<slug:slug>/', views.view_category_list, name='view_category_list'),
before it ever gets to the /?
Relevant view code:
def view_category_list(request, slug):
try:
category_detail = BusinessCategory.objects.get(slug=slug)
except BusinessCategory.DoesNotExist:
category_detail = None
if category_detail:
--code here is all working fine so removed it to get to the issue--
else:
raise Http404
I hoped raising the 404 would call up the redirect app to do its job at redirecting to a specific url but it doesn't - it just shows the custom 404 when debug is False. Anyway, the 404 is better than the 500 for SEO purposes but I still would prefer being able to actually redirect some of the URLs to relevant content.

LOGIN_REDIRECT_URL in django

I am very new to Django and I'm nearing the end of the django girls tutorial. I have added "#login_required" above my post_detail in views (view for clicking on a specific post) and added a login.html template. So when I click on a post title I get redirected to my login page (so far, so good) and the url is: http://127.0.0.1:8000/accounts/login/?next=/post/11/ (trying this on my computer atm.)
Then I type in my admin name/password and automatically get redirected to http://127.0.0.1:8000/accounts/profile/ and of course get a "Page not found (404)" (since I have no url/view/template for that). I thought "Dang, I just wanted to be redirected to /post/11/"!
Looked around on stack overflow and found this question:
Signing in leads to "/accounts/profile/" in Django (sounds about right)
and got the answer
Change the value of LOGIN_REDIRECT_URL in your settings.py.
So I looked up LOGIN_REDIRECT_URL in the Django documentation:
Default: '/accounts/profile/'
The URL where requests are redirected after login when the contrib.auth.login view gets no next parameter.
This is used by the login_required() decorator, for example.
This setting also accepts named URL patterns which can be used to reduce configuration duplication since you don’t have to define the URL in two places (settings and URLconf).
Deprecated since version 1.8: The setting may also be a dotted Python path to a view function. Support for this will be removed in Django 1.10.
But doesn't my contrib.auth.login get a next parameter? (looking at my url that say "?next=/post/11/" at the end) Please help me out here, I'm lost for what the problem could be here :(
You can view the page at:
http://finbel.pythonanywhere.com/
And the source code at:
https://github.com/Finbel/my-first-blog
UPDATE (1):
So I now know that the LOGIN_REDIRECT_URL is the thing that's deciding where I end up next, which must mean that it ignores the next-parameter in the url. I googled further on the problem and found this question which was very similar to my problem, i.e.
Documentation states that I need to use the "next" parameter and context processors. I have the {{next}} in my template, but I'm confused on how to actually pass the "/gallery/(username)". Any help would be greatly appreciated.
(I don't even have the {{next}} in my template, where/how should I add it?)
The preferred answer to that question seemed to be:
Django's login view django.contrib.auth.views.login accepts a dictionary named extra_context. The values in the dictionary are directly passed to the template. So you can use that to set the next parameter. Once that is done, you can set a hidden field with name next and value {{ next }} so that it gets rendered in the template.
But I'm not sure how to interpret this. While writing this edit I got an answer on this post (by kacperd) and will read it through now)
The problem is that contrib.auth.login doesn't get the next parameter.
When you try to get the login_required view without credentials your request is redirect to login view, and the template you created is rendered. The next parameter is present in this view, but when you perform the login action which is submitting the form, you are not including next in your request so contrib.auth.login doesn't get it and redirects to default page.
The solution to your problem is to include the next param and pass it forward. You can do this by modifying your login template. Simply add ?next={{ request.GET.next }} to form action attribute.
<form method="post" action="{% url 'django.contrib.auth.views.login' %}?next={{ request.GET.next }}">

How to write pattern for all other urls that basically goes for not found in django?

I tried this,
url ('', views.notfound, name='notfound')
But seems it doesn't work properly, for example, I have another url pattern define,
url(r'^login/$', views.login, name='login'),
So, if I go for http://example.com/login/, this works, but if i go for http://example.com/login/?help=1, then it falls into notfound category. How can I handle that?
If you just want to create a page that is displayed when a URL is not found (i.e. a Http404 exception is thrown) you can create a template with the name 404.html, and that template will be displayed any time a URL is not found.
Or if you want to define a custom 404 handler view you can define handler404 = views.notfound in your urls.py file. Then just create your notfound view, and that view will be used whenever a 404 error is thrown (and DEBUG = False)
This is a better way to catch any urls that are not recognized and display a friendly 404 page.
You can try with regex like this:
url(r'^.*', views.notfound, name='notfound'),
Make sure put it at the end of the urls.py
I think you may need to do something when url is not found, if you just need the 404 page, then the single 404.html in your templates works. And remember ti set DEBUG = False in your settings.py to see the 404 page in development environment.
Don't know what your use case is.Both above comments were equally right enough if u want to display a custom 404 page .Had u need something else to know. Check this out->
pip install django-extensions
then read this
then use the show-urls command to enlist all possible urls.
Do some manipulation or write testcases with assert to check not found urls.
Hope this is ok for your requirements or kindly comment with your suggestions cheers :-)

Django: Why can I reverse a URL in the template but not in a view?

There's some weird stuff happing with the URL reversal code in django 1.4.
I have a view called settings.views.app_view. I have viewed the page by typing in the URL manually to verify that the basic URL pattern is working.
url(r'^app/$', 'settings.views.app_view', name='settings_app_view'),
I have reversed the URL in a template and it works.
{% url settings_app_view %}
So, the URL pattern works, and I can call get the URL in a template, click the link and view the correct page.
So why can't I get the URL in a view using reverse()? All the code is clearly there, and not only that, it's clearly configured and working correctly as I've seen the page and reversed the URL in a template.
I have to be missing something small; does anyone know what it is?
ViewDoesNotExist at /settings/app/
Exception Value: Could not import settings.views.app_view. View does not exist in module settings.views.
# The highlighted code
url = reverse("settings_app_view")
Where exactly in your code does reverse() get executed? If reverse() gets executed during importing the python file, you can get a recursive import. Unfortunately a recursive import can have different results: AttributeError can happen on modules that should have this attribute....
See: https://docs.djangoproject.com/en/dev/ref/urlresolvers/#reverse-lazy

Django- trying to use APPEND_SLASH and a custom catchall 404 view

I generally add a catch-all 404 regex to my Django websites as the last expression in my urls.py:
urlpatterns += patterns('django.views.generic.simple',
(r'^.', 'direct_to_template', {'template': 'unknown.html'}),
I'm generally happy with the performance of this. The unknown.html template extends my base template and nicely tells the viewer that their entered url doesn't exist, but the page still has all the navigation and style of my website.
However, after having to repeatedly tell people to enter a trailing slash, I feel that the APPEND_SLASH = True parameter in settings.py needs to be set.
the docs state:
If APPEND_SLASH is True and the
initial URL doesn’t end with a slash,
and it is not found in the URLconf,
then a new URL is formed by appending
a slash at the end. If this new URL is
found in the URLconf, then Django
redirects the request to this new URL.
Otherwise, the initial URL is
processed as usual.
So following this logic, foo.com/bar is successfully caught by my "404" url expression before it can be redirect to my foo.com/bar/ url expression.
*What is the best way to maintain a friendly/custom catchall 404 page while also being able to use APPEND_SLASH or something with similar functionality?*
--edit/answer--
Somehow I missed that you just need to add a template named 404.html, and also make sure DEBUG = False
Thanks DTing!
I think you can just customize your 404.html instead of using a "catchall" since you are just redirecting to a custom template. There is no reason why your custom 404.html template can't extend your site's base.html.
http://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views
Three things to note about 404 views:
The 404 view is also called if Django doesn't find a match after
checking every regular expression in
the URLconf.
If you don't define your own 404 view -- and simply use the default,
which is recommended -- you still have
one obligation: you must create a
404.html template in the root of your template directory. The default 404
view will use that template for all
404 errors. The default 404 view will
pass one variable to the template:
request_path, which is the URL that
resulted in the 404.
The 404 view is passed a RequestContext and will have access to
variables supplied by your
TEMPLATE_CONTEXT_PROCESSORS setting
(e.g., MEDIA_URL).
If DEBUG is set to True (in your settings module), then your 404 view
will never be used, and the traceback
will be displayed instead.
if you do want to use a custom view,
This page_not_found view should
suffice for 99% of Web applications,
but if you want to override the 404
view, you can specify handler404 in
your URLconf, like so:
handler404 = 'mysite.views.my_custom_404_view'