I have set up django to work in my local environment. I have a python function which takes two parameters and returns data in JSON format. This is set up in my views.py and urls.py as follows:
views.py :
from django.http import Http404, HttpResponse
from X import calculate
def calculate_X(request, para1, text):
#para1 is ignored on purpose
return HttpResponse(calculate(text))
urls.py :
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^calculate-X/(\d+)/([a-zA-Z0-9_ ]*$)',calculate_X),
url(r'^$', TemplateView.as_view(template_name='base.html')),
]
urlpatterns += staticfiles_urlpatterns()
In the base.html file I have a single button which should make the request to the calculate-x url as follows /calculate-X/1/stringdataexample
which would then create an alert() with the contents of the httpresponse ( JSON )
How can I make this request?
(There is another question asked here on SO however it uses request processors which do not relate to my question)
one way could be to trigger an ajax call when you click that button, and then process the response as you wish.
The button's html could be something like this:
<button onclick="processCalculation()">Calculate!</button>
Something like this function:
function processCalculation(){
var para1 = $("#params-container").val();
var text = $("#text-container").val();
$.ajax({
url: "/calculate-X/" + para1 + "/" + text,
data: {}
}).done(function (jsonResponse) {
alert(jsonResponse)
});
}
I hope this points you on the right direction, Best regards!
Related
UPDATE: Added the code I was accessing that threw the error
For a CS50 project I'm working on with a wiki page, I'm trying to send the right custom 404 error when a user types a page that doesn't exist in wiki/TITLE however when I type a missing page, Django throws a 500 instead of a 404. Is this a common error or did I make my error message wrong? Debug is set to False and Allowed Hosts is configured to ['*'] in settings:
Here's my custom error handlers in views.py:
def error_404(request, exception):
context = {}
response = render(request, 'encyclopedia/error_404.html', context=context)
response.status_code = 404
return response
def error_500(request):
context = {}
response = render(request, 'encyclopedia/error_500.html', context=context)
response.status_code = 500
return response
Here's how they are in wiki/urls.py:
from django.contrib import admin
from django.urls import include, path
from django.conf.urls import handler404, handler500
urlpatterns = [
path('admin/', admin.site.urls),
path('', include("encyclopedia.urls")),
]
handler404 = "encyclopedia.views.error_404"
handler500 = "encyclopedia.views.error_500"
here's the function in views.py that I'm accessing but going to wiki/C:
#function gets entry from index.html's <li>
def entry_page(request, entry):
name = entry # Places the title
print(f"checking the title: {entry}")
text = util.get_entry(entry) # Grabs the entry using the util function
html = md_converter(text)
if text is not None:
return render(request, "encyclopedia/entry.html", {
"title": name,
"entry": html
})
And here's my urls.py for good measure:
from django.urls import path
from . import views
app_name = "encyclopedia"
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:entry>", views.entry_page, name="entry"),
path("wiki/edit/<str:title>", views.edit, name="edit"),
path("search", views.search, name="search"),
path("random", views.random_page, name="random"),
path("create_entry",views.create_entry, name="create_entry")
]
Here's what the terminal shows (my styles.css is throwing a 404 for some reason but I haven't changed anything there...that's a separate issue):
There could be something wrong with your code. Django doc clearly says
The 404 view is also called if Django doesn’t find a match after checking every regular expression in the URLconf.
https://docs.djangoproject.com/en/3.2/ref/views/#error-views
Figured it out. Thanks ya'll.
There was an error in the function I was using to grab the page. I wasn't checking to see if the URL was valid when looking up a particular wiki entry.
Changing entry_page in views.py to this made it work!:
def entry_page(request, entry):
if entry in util.list_entries():
name = entry # Places the title
text = util.get_entry(entry) # Grabs the entry using the util function
html = md_converter(text)
return render(request, "encyclopedia/entry.html", {
"title": name,
"entry": html
})
else:
return render(request, "encyclopedia/error_404.html" )
Glad it wasn't Django messing up, just me lol
Django is unable to load my template because "NoReverseMatch at /books/outlines/20
"
This issue lies within a link in the template:
New Blank Outline
Here is my outlines/urls.py
from django.urls import path
from .views import Dashboard
from . import views as outline_views
urlpatterns = [
path('<int:pk>/', outlines_views.outline, name='url-outline')
path('blank/<int:storyPk>', outline_views.newBlankOutline, name='url-blankOutline'),
path('test/', outline_views.testView, name = 'test')
]
urlpatterns += staticfiles_urlpatterns()
Here is the testView:
def testView(request):
return render(request, 'outlines/test.html')
Here is the outline view:
def outline(request, pk):
context = {
'storyPk': pk
}
return render(request, 'outlines/outline.html', context)
The django error tells me:
NoReverseMatch at /books/outlines/20
Reverse for 'test' not found. 'test' is not a valid view function or pattern name.
The weird thing is, if I change the url name in the template to a url name from another app's urls.py file, it renders the template no problem. Any idea why it can't find the url?
New Blank Outline
how about try this
I have a loading page in Django while some server side processes are ongoing the view is;
def loading_page( request ):
testname = request.session['testname']
done_file = filepath_to_design_dir( testname + ".done" )
if os.path.exists( done_file ):
request.session["job_stat"] = "job_done"
return redirect( "single_output/")
else:
return render( request, 'single_design/loading.html' )
My problem is that the redirect goes to;
http://127.0.0.1:8000/single_design/loading_page/single_output/
Rather than
http://127.0.0.1:8000/single_design/single_output
What is the correct way to do this???
EDIT : issue resolved, thanks guys.
Urls as requested
from django.conf.urls import url , include
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', views.get_single_input, name='single_design_input'),
url(r'^single_output/$', views.single_output, name='single_output'),
url(r'^loading_page/$', views.loading_page, name='loading_page'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
The correct way is not to use hardcoded link. Use urlresolvers.
return redirect("some_view_name")
Without the leading slash, the current value single_output/ is treated as a relative url, which is appended to the current url /single_design/loading_page/ to give /single_design/loading_page/single_output/.
You could use the relative url ../single_output, but I wouldn't recommend it. It would be better to return the url you want to redirect to, including a leading slash.
return redirect('/single_design/single_output/' )
Ideally, you should use the name of the url pattern, then Django will reverse it for you. Since you have,
url(r'^single_output/$', views.single_output, name='single_output'),
you can use the name instead of the url,
return redirect('single_output')
The advantage of using the name single_output, is that you can now change the URL in your url patterns, without having to update the view.
I've got to test URLs that look like this:
http://127.0.0.1:8000/payment/pay/513623c9/
but I'm not sure how to say this to the reverse() function. This is my urls.py
from django.conf.urls import patterns, url
from payment import views
from payment.msn import *
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^msnstats/', MsnStats.finish_transaction, name='finish_transaction'),
url(r'^pay/(?P<payment_id>\w+)/$', views.pay, name='pay')
)
And this is what the relevant part of my views.py looks like:
def pay(request, payment_id):
try:
plan=PaymentPlan.objects.get(payment_id=payment_id)
The payment_id is generated for each plan, so I first create a plan, get its payment_id from the database, and somehow call it. I'm just not sure how to use reverse.
from django.core.urlresolvers import reverse
url = reverse('pay', args=[plan.payment_id])
or
url = reverse('pay', kwargs={'payment_id': plan.payment_id})
Both versions are valid.
UPDATE: If you include the payment.urls with namespace argument then you have to add this namespace to the url name in the reverse() call:
project/urls.py:
url(r'^payment/', include('payment.urls', namespace='payment')),
payment/tests.py:
response = self.client.get(reverse('payment:pay', args=[plan.payment_id]))
When passing the X-CSRFToken header or sending csrfmiddlewaretoken in the POST data to my view, it completely skips the ajax handler and goes directly to the index/base view.
Javascript:
$.post("/action/register", {
name: $('#input_name').val(),
email: $('#input_email').val(),
csrfmiddlewaretoken: '{{ csrf_token }}'
}, function(data) {
var response;
try {
response = JSON.parse(data.toString());
} catch(e) {
response = {"status":"error", "message":"Please try again later, we're having some tech issues!"};
}
// ... process some stuff, the callback works which is good
View:
def handle_register(req):
''' Request handler pyfor registration, should return JSON for the AJAX request. '''
if req.is_ajax():
return validate_and_register(req)
else:
return HttpResponse('{"status":"error","message":"Invalid request."}')
urls.py:
from django.conf.urls.defaults import *
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^action/register$', 'views.handle_register', name='handle_register'),
url(r'^admin/', include(admin.site.urls)),
url(r'^.*$', 'views.handle_home', name='handle_home'),
)
When I don't pass the header, i get a 403 (CSRF_VERIFICATION_FAILED). When I pass the appropriate header (confirmed in multiple browsers) it skips the /action/register handler and goes directly to the "handle_home" view.
I'm stuck!
This could possible be due to a missing slash on your url
/action/register
Try adding a slash in url and in your javascript.
Another guess would be:
'views.handle_register'
is missing an app name?
A more safe was as well would be to use reverse urls:
from django.core.urlresolvers import reverse
url = reverse('appname.views.handle_register')
$.post(url, {}, func...
This was an issue with nginx. Per the django/nginx setup docs I found I was missing this in my nginx config:
fastcgi_split_path_info ^()(.*)$;