why django does not find the url? - python

I'm new to django, and I'm trying to access the following web page by clicking on "dataset celiac" and acces so to "celiac.html". On the html side, here is my code which corresponds to this part of the page where I click on "dataset celiac":
<div class="visit">dataset celiac</div>
Then, on the views.py side, here is the code corresponding to the view which is supposed to return the html page to celiac.html:
def CeliacView(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = forms.CeliacForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
columns = form.cleaned_data['columns']
algo = form.cleaned_data['algo']
if algo == "Logistic regression" and columns == 'CDR3_IMGT':
return render(request, 'data/cdr3.html', locals())
else:
tableData = get_table_data_to_representation()
context = {'form': forms.CeliacForm(), 'tableData': tableData}
return render(request, 'data/celiac.html', context)
And regarding the urls.py file here is my code:
app_name = 'data'
urlpatterns = [
path('datasets/', views.SetView, name='datasets'),
path('celiac/', views.CeliacView, name='celiac'),
]
Finally, here is what django shows me when I click on celiac dataset: Page not found (404)
Can someone tell me what could be the problem here please? why django does not find the correct url ?

Your href shouldn't be the filename, put the path where your url points you towards. For making it more dynamic, I'd suggest using the url tag. Like so:
<div class="visit">dataset celiac</div>

Related

Django: User Reporting Some URL on Website

So i'm trying to build something, so that users would be able to report something on site. Here's the model,
class Report(models.Model):
reporting_url = models.URLField()
message = models.TextField()
I created Form for this Model including 'message' field only because 'reporting_url' is something it needs to populate by itself depending upon the specific page from where user has clicked "Report" button.
def report(request):
url_report = ???
if request.method == 'POST':
form = ReportForm(request.POST or None)
if form.is_valid():
new_form = form.save(commit=False)
new_form.reporting_url = url_report
new_form.save()
I was wondering How can I pass the specific url to 'reporting_url' field in form depending on the Page from where user has clicked "Report" button? (Much like s we see on social Networks).
Am I doing this correctly, Or is there a better way for doing this?
Please help me with this code. Thanks in Advance!
If there is a report button on that specific page then I believe you could write custom context processor.
More info: Django: get URL of current page, including parameters, in a template
https://docs.djangoproject.com/en/1.11/ref/templates/api/
Or maybe just write it directly in the views.py in your function and set
url_report = request.get_full_path()
I think you can use the form on the same page of the URL and use:
url_report = request.get_full_path()
in the view, to get the current URL.
Else if you want to create a separate view for the reporting form. You can use
url_report = request.META.get('HTTP_REFERER')
to get the previous or refering URL which led the user to that page.
request.META.get('HTTP_REFERER') will return None if it come from a different website.

I want something to be executed through django

I know this question was asked before, but none worked for me. I have this code that I want it to be executed when a button is clicked and a message is passed
import time
from sinchsms import SinchSMS
number = '+yourmobilenumber'
message = 'I love SMS!'
client = SinchSMS(your_app_key, your_app_secret)
print("Sending '%s' to %s" % (message, number))
response = client.send_message(number, message)
message_id = response['messageId']
response = client.check_status(message_id)
while response['status'] != 'Successful':
print(response['status'])
time.sleep(1)
response = client.check_status(message_id)
print(response['status'])
Basically, what I need is to add an input in a template "HTML File", this input get passed to the message variable in the code above, same with the number. I can easily do that with instances, but how can the below get executed when a button is clicked from the form in the template?
I'm kinda newbie in Django and still finding my way
Here is the tutorial that explains how to make the python file, but execute it from the shell, not a django application.
I hope I was clear describing my problem and any help would be appreciated!
All you need is a form with a message field. In a view, you want to show that form and when the user press submit, you want to execute your script.
Here is some pseudo-code:
urls.py
url('^my-page/' my_views.my_view, name='my-page'),
forms.py
SmsForm(forms.Form):
message = fields.CharField(...)
my_views.py
def my_view(request):
form = SmsForm(data=request.POST or None)
if request.method == 'POST':
if form.is_valid():
send_sms(form.cleaned_data['message']) # do this last
messages.success(request, "Success")
return HttpResponseRedirect(request.path)
else:
messages.warning(request, "Failure")
return render(request, 'my_template.html', {'form': form})
Check the Django documentation about urls, views, forms and messages and proceed step by step:
get the page to load
get the form to load
get the form submission to work and simply show "Success" or "Failure"
finally, write the send_sms function (you've almost done it)
Lets start from the dust cloud.
What you are asking is mostly about how the web pages work. You need to know how to pass parameters using HTML. There are lots of ways to do it. But with django there is a pattern.
You need a url, and a view to catch any requests. Then you need to create a template and a form inside it. With this form you could create some requests to send data to your view.
To create you need to edit urls.py inside your project add an url:
urls.py
from django.conf.urls import url
from my_app.views import my_view
urlpatterns = [
...
url(r'^my_url$', my_view, name='my_view')
...
]
For more about urls please look at URL dispatcher page at documentation.
Then create your view inside your app which is my_app in my example. Edit my_app/views.py
my_app/views.py
from django.http import HttpResponse
def my_view(request):
return HttpResponse('IT WORKS!')
This way you get a working view which could be accessed with path /my_url. If you run ./manage.py runserver you could access your view from http://localhost:8000/my_url.
To create a form you need to create a template. By default django searches app directories for templates. Create a templates directory in your app, in our case my_app/templates and create an HTML file inside. For example my_app/templates/my_form.html. But i advice to create one more directory inside templates directory. my_app/templates/my_app/my_form.html. This will prevent template conflicts. You can check Templates page at documentation for more.
my_app/templates/my_app/my_form.html
<html>
<body>
<form action="/my_url" method="POST">
{% csrf_token %}
<input type="text" name="number">
<input type="text" name="message">
<input type="submit" value="Run My Code">
</form>
</body>
</html>
This is the one of the ways of creating your form. But I do not recommend it. I will make it prettier. But first lets "Make it work", edit your views.py:
csrf_token is a django builtin template tag, to put CSRF token into your form. By default django requires CSRF tokens at every post
request.
my_app/views.py
from django.http import HttpResponse
from django.shortcuts import render
def my_view(request):
if request.method == 'GET':
return render('my_app/my_form.html')
elif request.method == 'POST':
# get post parameters or None as default value
number = request.POST.get('number', None)
message = request.POST.get('message', None)
# check if parameters are None or not
if number is None or message is None:
return HttpResponse('Number and Message should be passed')
# your code goes here
...
return HttpResponse('Your code result')
Till this point the purpose of this answer was "Making it work". Lets convert it nice and clean. First of all we would create Form. Forms are like models, which helps you create forms as objects. It also handles form validations. Forms are saved inside forms directory generally. Create my_app/forms.py and edit it:
my_app/forms.py
from django import forms
class MyForm(forms.Form):
number = forms.CharField(max_length=15, required=True)
message = forms.CharField(max_length=160, required=True)
Put your form inside your template:
my_app/templates/my_app/my_form.html
<html>
<body>
<form action="{% url 'my_view' %}" method="POST">
{% csrf_token %}
{{ form }}
</form>
</body>
</html>
Besides the form, the action of the HTML form tag is also changed.
url template tag is used to get url form url name specified in urls.py.
Instead of url tag, {{ request.path }} could have been used.
Create a form instance and pass it to the template rendering:
my_app/views.py
from django.http import HttpResponse
from django.shortcuts import render
from .forms import MyForm
def my_view(request):
if request.method == 'GET':
form = MyForm()
return render('my_app/my_form.html', {'form': form})
elif request.method == 'POST':
form = MyForm(request.POST)
# check if for is not valid
if not form.is_valid():
# return same template with the form
# form will show errors on it.
return render('my_app/my_form.html', {'form': form})
# your code goes here
...
return HttpResponse('Your code result')
You can use class based vies to write your view, but it's not necessary. I hope it helps.
You can create a view that takes up query parameters from the url and use it for further implementation. Then you can create a link/button in the html template which can redirect you to that url. For example:
in urls.py:
url(r'^run_a/(?P<msg>\w{0,25})/(?P<num>\w{0,25})/$', yourcode, name='get_msg'),
in template:
submit
in views.py:
def get_msg(request,msg,num):
message=msg
number=num
#rest of the code
Hope this helps :)

Django work flow redirect from one view to another and display page with url parameter

I am trying to create a web app that users will select a file, get data processed and then redirected to a confirmation page with a url parameter(?status=1) How can I move from the processing view to the confirmation view and then display the confirmation page?
I have put my code below which is not working in my views and urls py files
# views.py
def marketdata_processing(request):
if request.method == 'POST':
uploadform = forms.MyUploadForm(request.POST, request.FILES)
if uploadform.is_valid():
newdoc = models.UploadDocument(docfile=request.FILES['uploadfile'])
filename = request.FILES['uploadfile'].name
newdoc.save()
selecteddate = newdoc.getselecteddate() # Model method calculated
fileid = newdoc.pk
request.session['fileid'] = fileid
request.session['selecteddate'] = selecteddate
return redirect(reverse('views.confirm_input_details'))
else:
uploadform = forms.MyUploadForm()
# Render list page with the documents and the form
return render_to_response(
'mytemplate.html',
{'uploadform': uploadform},
context_instance=RequestContext(request)
)
def confirm_input_details(request):
fileid = request.session['fileid']
selecteddate = request.session['selecteddate']
msg = 'Proceed to import data for %s? \nFileID Being Imported is %s ' % (
selecteddate, fileid,)
url = reverse('views.confirm_input_details', kwargs={'status': 1})
return HttpResponseRedirect(url)
# urls.py
urlpatterns = [
url(r'', views.marketdata_processing, name='myapp/mytemplate.html'),
url(r'^\?status=(?P<status>[0-9]+)$',
views.confirm_input_details, name='myapp/myconfirmpage.html'),
]
There are a couple of issues I feel exist in your code:
Indentation is a very important thing in python code. Please make sure the indentation of your if-else statements in the 'marketdata_processing' view are in correct order. Beware, in your code:
return render_to_response('mytemplate.html',
{'uploadform': uploadform},
context_instance=RequestContext(request))
will always get executed as it is outside the else statement. You might want to indent it under the else (if it makes sense)- like so:
else:
uploadform = forms.MyUploadForm()
return render_to_response('mytemplate.html',
{'uploadform': uploadform},
context_instance=RequestContext(request))
Instead of 'redirect(reverse())' try 'HttpResponseRedirect()' in the processing view to call the confirm-page view, like so:
from django.http import HttpResponseRedirect
return HttpResponseRedirect('/?status=1') --> relative URL shown
place the relative/absolute url (both would work) above.
Finally, render your confirm-page template in the 'confirm_input_details' view with the context parameters, like so:
def confirm_input_details(request):
fileid = request.session['fileid']
selecteddate = request.session['selecteddate']
msg = 'Proceed to import data for %s? \nFileID Being Imported is %s ' % (selecteddate, fileid)
return render_to_response('confirmpage_template.html'),
{'fileid': fileid,
'selecteddate': selecteddate,
'msg': msg}, context_instance=RequestContext(request))
** P.S: Stick to neat basics and it will work. You happened to call your confirm_input_details view from within the same view itself. As far as I think, that would probably take you into an infinite loop. Simple concept of any view is:
take input:request, parameters
--> process logic with parameters
--> render a specific template or call another url where a template is being rendered.
You can't expect a page to show up without the rendering a template.

Moving Between Pages

I am trying to move from a web page to another when the user submits a POST.
The problem is that the url doesn't change when I submit the POST and the view function that corresponds to the new page doesn't fire but the template loads and it show only the inputs I hard coded inside it without those I pass in the view function of course.
The Code:
In the urls file:
url(r'^addcross/phase1', views.new_cross_phase_1, name='new_cross_phase_1'),
url(r'^addcross/phase2', views.new_cross_phase_2, name='new_cross_phase_2'),
The view function of the 1st page:
def new_cross_phase_1(request):
if request.method == 'POST':
# my code here
return render_to_response('New/New_Cross_Phase_2.html', {'crosses_names': crosses_names, 'creation_methods' : creation_methods},
context_instance=RequestContext(request))
The view function of the 2nd page:
def new_cross_phase_2(request):
print('Phase 2')
if request.method == "GET":
return render_to_response('New/New_Cross_Phase_2.html', {'cross_form': new_cross_form},
context_instance=RequestContext(request))
You should be redirecting in view 1, not rendering the template from view 2.
return redirect('new_cross_phase_2')

django: redirecting to another app's view not properly

App1 containing the form, after user fulfills and submits the form, the page will redirect to "Result" which is defined in App2
def input(request):
if request.method == 'POST':
form = Inputform(request.POST)
if form.is_valid():
cd = form.cleaned_data
print (cd['company'])
print (cd['region'])
return HttpResponseRedirect(reverse('result', args=(p.id,)))
The url is as below:
urlpatterns = patterns('',
url(r'^result/$','result.views.resultlist',name='result'),
url(r'^input', 'inputform.views.input',name='input'),
The thing is if I run http://127.0.0.1:8000/result on the browser, it works properly. But once I fulfill the form and click the submit, the page will redirect to:http://127.0.0.1:8000/result.html. And then there is error showing:
The current URL, result.html, didn't match any of these.
Any suggestion is highly appreciated. Thanks.
try
return redirect('result', args=(p.id,))

Categories