I have a PDF uploading form. When a user sends this form I want to trigger a URL in my views. I want the invoked URL address to be opened only once in the backend. The user cannot view this page. The reason I want this is that the API I call from here enables me to do another process.
How can I run an URL in my views backend?
Note: Does using this work?
r = requests.get(url)
views.py
def upload_pdf(request, id):
if request.method == 'POST':
customer = get_object_or_404(Customer, id=id)
form = PdfForm(request.POST, request.FILES)
if form.is_valid():
new_pdf = form.save(commit=False)
new_pdf.owner = customer
new_pdf.save()
name = new_pdf.pdf.name.replace(".pdf", "")
url = 'https://api..../perform/{0}'.format(name)
return redirect('ocr', id=new_pdf.id)
else:
form = PdfForm()
customer = get_object_or_404(Customer, id=id)
return render(request, 'upload_pdf.html', {'form': form, 'customer': customer})
import requests
url = request.get/post('https://api..../perform/{0}'.format(name))
Related
I'm building a website, to be used in dental practices, however I'm having trouble with the URL routing. I'm wanting af URL pattern like: Denthelp/kartotek/#nameofclinic#/opretpatient.
My suggestion looks like this:
urls.py:
path('kartotek/<str:kl_id>/', views.kartotek, name="kartotek"),
path('kartotek/<str:kl_id>/opretpatient/', views.opretpatient, name="opret_patient"),
Views. py:
def kartotek(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
E_patient = kliniknavn.patient_set.all()
context = { 'kliniknavn':kliniknavn, 'E_patient':E_patient}
return render(request,'DentHelp/kartotek.html', context )
def opretpatient(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
form = PatientForm()
if request.method == 'POST':
form = PatientForm(request.POST)
if form.is_valid():
form.save()
return redirect('kartotek/<str:kl_id>/')
context = {'form':form, 'kliniknavn':kliniknavn}
return render(request,'DentHelp/kartotek/<str:kl_id>/opretpatient.html', context)
When running code I get an OSError for the last line of code shown here.
Have you guys have any advise for this to work?
You are mixing up render with redirect. render renders a template dynamically with attributes from context, where redirect redirects the user to a different view. To call render, you need to provide template name and context. For redirect, you need to provide url name and parameters (if required). Here is how you should do in your code:
def opretpatient(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
form = PatientForm()
if request.method == 'POST':
form = PatientForm(request.POST)
if form.is_valid():
form.save()
return redirect('kartotek', kl_id) # url name and parameter
context = {'form':form, 'kliniknavn':kliniknavn}
return render(request, 'DentHelp/kartotek/opretpatient.html', context) # template name and context
I am trying to get or create an object when another one is created with a form :
def index(request, log_id, token):
log = get_object_or_404(LogBook, pk=log_id)
logmessages = LogMessage.objects.filter(logbook=log_id)
form = CreateLogMessage(request.POST)
if request.method == "POST":
if form.is_valid():
instance = form.save(commit=False)
instance.reported_by = request.user
instance.logbook = log
instance.save()
logdone = LogDone.objects.get_or_create(logmessage=logmessages, done_status=False)
I am trying to figure out a way to get the id of the logmessage created to pass it to my logdone instance.
I don't find a way to do it so far, any help will be appreciate it.
The object that is created is the instance, you thus can implement this as:
from django.shortcuts import redirect
def index(request, log_id, token):
log = get_object_or_404(LogBook, pk=log_id)
if request.method == 'POST':
form = CreateLogMessage(request.POST)
if form.is_valid():
form.instance.reported_by = request.user
form.instance.logbook = log
instance = form.save()
logdone = LogDone.objects.get_or_create(
logmessage=instance,
done_status=False
)
return redirect('name-of-some-view')
else:
form = CreateLogMessage(request.POST)
…
Since your form creates a new object every time, this however always create an object.
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
I have developed a simple django project in which photos will be stored and displayed. The problem is whenever I redirect to a page, the page gets loaded but the url does not change in the address bar. So when i refresh the page again, I am getting errors. For example,
I created an album. For that the url is: 127.0.0.1:8000/create_album/
Then it has to redirect to the albums page where all albums of user are stored.
That url is 127.0.0.1:8000/10/
But i am not getting that url when i redirect to that page.
The views.py:
**def create_album(request):
if not request.user.is_authenticated():
return render(request, 'photo/login.html')
else:
form = AlbumForm(request.POST or None, request.FILES or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.album_logo = request.FILES['album_logo']
album.save()
return render(request, 'photo/detail.html', {'album': album})
context = {
"form": form,
}
return render(request, 'photo/create_album.html', context)
def detail(request, album_id):
if not request.user.is_authenticated():
return render(request, 'photo/login.html')
else:
user = request.user
album = get_object_or_404(Album, pk=album_id)
return render(request, 'photo/detail.html', {'album': album, 'user': user})**
The page has to be redirected to photo/detail.html. It redirects to the required page but the url doesn't change. Please help me with this.
It is good practice to do a redirect upon submitting a form. Here's how you can change your code to perform the redirect:
from django.shortcuts import render, redirect
from django.urls import reverse
def create_album(request):
if not request.user.is_authenticated():
return render(request, 'photo/login.html')
else:
form = AlbumForm(request.POST or None, request.FILES or None)
if form.is_valid():
album = form.save(commit=False)
album.user = request.user
album.album_logo = request.FILES['album_logo']
album.save()
return redirect(reverse('detail', kwargs={'album_id':album.id}))
context = {
"form": form,
}
return render(request, 'photo/create_album.html', context)
This assumes that the url/view is named detail in your url patterns.
You could try this first, and if it doesn't work could we see your HTML code for the form?
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()
Here's the view,
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 can't use something like,
url_report = request.get_full_path()
since I need to create/edit several views & repeat things in that case.
When I'm using something like,
url_report = request.META.get('HTTP_REFERER')
it's returning the URL of same page from where the from is written. I'm using something like,
Report
to reach the Report form from several different apps/html_pages.
How can I get the URL of previous page from where user has pressed the "Report" button?
Please help me with this code!
You could store the referer in the session whenever the Report button is pressed:
def report(request):
if request.method == 'GET':
request.session['report_url'] = request.META.get('HTTP_REFERER')
# ...
if request.method == 'POST':
form = ReportForm(request.POST or None)
if form.is_valid():
new_form = form.save(commit=False)
new_form.reporting_url = request.session.get('report_url')
new_form.save()
You have to persist this referer beyond one request-response cycle. The session is the designated way to do that. Another option would be to render that url as a hidden form field, but that can be easily tampered with.
I am working on a web application which works with entities that all have their unique IDs.
I have a submit form for users to create these entities and this form is in several steps (i.e. view 1 redirects to view 2, etc... until the end of the submission process).
The first view will create the ID of the entity after form submission and I then need to use the ID of the instance created in the other views.
I do not want to pass this ID as a URL parameter to the other views as these will be POST and that means that users could easily manipulate these and create records in models for several IDs. I have managed to pass this ID to several views using the session parameters (request.session) but this is not ideal as this is permanent for the session. Current code below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
request.session['xxx_id'] = xxx_entry.id
return HttpResponseRedirect(reverse('form_2'))
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = request.session['property_id']
if xxx_id == 'SET_BACK_BLANK':
return render(request, 'no_xxx_id.html')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
request.session['xxx_id'] = 'SET_BACK_BLANK' #to avoid the misuse during other user interactions.
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
Ideally, I would like to pass this ID parameter in the headers of the response as this will avoid having the ID as a session parameter. So I have amended the code to the below:
def view1(request):
if request.method == 'POST':
form = xxx_creation_form(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
... object creation ...
)
response = HttpResponseRedirect(reverse('form_2'))
response['xxx_id'] = xxx_entry.id
return response
else:
form = xxx_creation_form()
return render(request, 'xxx_form.html', {'form': form})
def view2(request):
xxx_id = HttpResponseRedirect(request).__getitem__('xxx_id')
if request.method == 'POST':
form = xxx_form2(request.POST)
if form.is_valid():
cleaned_form_data = form.cleaned_data
xxx_entry = Model.objects.create(
id = xxx_id, #use the id created in step 1
... rest of object creation ...
)
return HttpResponseRedirect(reverse('thanks'))
else:
form = xxx_form2()
return render(request, 'xxx_form2.html', {'form': form})
However the above does not work and the error message seems to indicate that there is no 'xxx_id' in the response header.
It would be great if anyone could let me know how to access a response's header in a view as it seems that we cannot amend the request's headers.
Thanks.
What you're asking doesn't really make sense. The response is what is sent from Django to the browser, it is not what the browser sends to Django. That's a completely separate request; in the case of a redirect, your response is simply an instruction to the browser to make that request to a new URL.
The correct thing to do is to use the session, as you are doing. If you are worried about the value being persisted, then pop it out of the session when you use it:
xxx_id = request.session.pop('property_id')