Django: Pass arguments in View and display on the page - python

Say, I've got 2 views in views.py: Fetching_information_view and Processing_view.
In Fetching_information_view I am fetching information which I am displaying to the user in the tabular format on the "home.html" page. That's all okay.
Now, I get a CSV URL for each row as well. I don't want that when the user clicks on the CSV URL it should open the CSV; instead, when the user clicks on it then it should go to the Processing_view and it should be served on a different HTML page, say "process.html".
CSV URL:
/some_bucket/some_csv_file.csv?AWSAccessKeyId=some_id&Expires=1234&Signature=some_signature
Desired URL:
http://example.com/process.html?file=some_bucket/some_csv_file.csv?AWSAccessKeyId=some_id&Expires=1234&Signature=some_signature
Now, how can I call Processing_view from the Fetching_information_view view and send the file information? It should process in the backend and display results on process.html.
This is the table I am showing on the homepage:
I've wrote sample code for views.py which I'm using:
def process_data(request):
# what should come here?
# Display in process.html
def home(request):
some_data = SomeTable.objects.filter(user = request.user)
args = {"some_data": some_data}
# display as table on home.html, including URLs it is carrying
return render(request, "home.html", args)

If you don't want to expose the URL of your CSV files, then don't add it (and also don't expose the URL parameters) to the context of your home view and template.
So assuming you've created a urlpattern named process_view for your process_data view, in your home.html template you can just use href="{{% url 'process_view' %}?id={{ id }}" to append the id of the object to your request's URL parameters.
Then in the process_data view, you can get this id by id = request.GET.get('id'), fetch the model with this id and reconstruct the CSV url and file parameters.

Related

Returning a filter result in a different page - Django

I've searched up but nothing seams to do the trick or be on point.
Let's say i have two websites on page A.html I have a filter (djnago_filter) and B.html is empty. If the user submits the search form he is redirected from page A.html to page B.html where the results are displayed with for loop.
How do I to that?
I was thinking about passing the data from query set to another view but there must be better solution to this.
There are several ways to store and display information on the different views(pages):
You could use the Sessions:
#views.py
#set the session key in the view A:
request.session['info'] = {'key', 'value'}
#get the session key in the view B:
info = request.session['info']
del request.session['info']
You could use Models with JSONField:
#app/models.py
#model to store information from page A
from django.contrib.auth.models import User
class MyModel(models.Model):
user = models.ForeignKey(User,
on_delete=models.DELETE,
related_name="info")
info = models.JSONField()
#views.py
#store data in the view A:
from app.models import MyModel
MyModel.objects.create(user=request.user, info={'key', 'value'})
#retrieve data in the view B:
info = MyModel.objects.get(user=request.user)
But actually, all depends on the logic that you intent to achieve. There are actually other methods like using async Ajax, React, WebSockets...
you can pass it as an HTML request parameter inside the url, for example, in your pageA template will be
to page B
and inside pageb view, you can take the filter from the request object
def page_b_view(request):
some_filter = request.GET.get('some_filter')

Showing a generated document using django

I have a Django site and want it so that when the user presses a button on the site that a python file makes a word document and shows it to the user in the browser.
I am getting an error saying that context must be a dict rather than set.
my document seems to be made in my pycharm project folder but it doesn't want to show itself for some reason.
my process is as follows: user clicks a html button. urls.py then points the browser to a function in my view.py called making_the_doc. This making_the_doc function runs a function in my the plot.py file which will generate the document and returns it to view.py for presentation to the user.
Firstly i created the code that will generate the document. This file is known as theplot.py.
THEPLOT.PY
def making_a_doc_function(request):
doc = docx.Document()
doc.add_heading('hello')
doc.save('this is doc.docx')
generated_doc = open('this is doc.docx', 'rb')
response = FileResponse(generated_doc)
return render(request, 'doc.html', {response})
Then I linked this function to my views.py
VIEWS.PY
def making_the_doc(request):
return making_a_doc_function(request)
Then i created my url paths to point to the views.py
URLS.PY
path('making_a_doc', views.making_the_doc, name='doc'),
finally I generate my html button so the whole process can start off when the button is clicked:
INDEX.HTML
<input type="button" value="generating" onclick="window.open('making_a_doc')">
You are not passing a dict to your render function. A change like this should make it work
def making_a_doc_function(request):
doc = docx.Document()
doc.add_heading('hello')
doc.save('this is doc.docx')
generated_doc = open('this is doc.docx', 'rb')
response = {"generated_doc": FileResponse(generated_doc)}
return render(request, 'doc.html', response)

Calling a function from HTML to Python file

I have a index.html page with a list of "cards", where each card have a "Click to Select" link.
When user click in this link i'd like to call a function in python to select this item, see:
def selectItem(request, item):
#so something with this item
so, in my html pagE:
<div class="card-action">
Selecionar
</div>
This don't work. What is the right way to do it ?
You can not call a function like that. A browser requests data with an HTTP request, and the server answers with an (HTTP) response. Such requests have a URL, and Django can route the request - with the URL - to the right view that will calculate a response.
We thus need to construct a view that can then be called. Your call is already quite close:
# app/views.py
from django.http import HttpResponse
def select_item(request, item_id):
# so something with this item_id
# ...
return HttpResponse()
Since most objects are not serializable (and usually you do not want that anyway, since it would expose a lot of (potentially sensitive) data to the user, we thus need to work with an id (an identifier that is for example stored in the database that corresponds to an object).
The response contains the data in the response. Frequently that is HTML code that is then rendered by the browser.
Now in urls.py, we can specify how the url looks like, for example:
# app/urls.py
from django.urls import path
from app.views import select_item
urlpatterns = [
path('select_item/<int:item_id>/', select_item, name='select_item_view'),
# ...
]
The urlpatterns need to be included in the root urlpatterns (in the project root).
Now in the HTML template, we can generate the URL that matches with this view, something similar to:
<div class="card-action">
Selecionar
</div>
Django will then make sure that the href points to an URL that refers to the select_item view with the correct parameter.

How to execute script python when i click button in form html?

hello how can i run script that i build on python when i click button on form html
i saw examples like this but i dont get it:
Html code: index.html
<form action="{% url my_view %}" method="post">
<input type="submit" value="Ok">
</form>
views.py
import django.shortcuts import render
def my_view(request):
if request.method == 'POST':
import set_gpio
#my url is "templates/load.py"
return #How can i return?
You need to return an HttpResponse object from your view. You can return one response inside your if statement, and another outside of it (so anything but a POST). Usually the render shortcut is used to render a response from a template. So your view would be something like:
import django.shortcuts import render
def my_view(request):
if request.method == 'POST':
# The user clicked the button (POST)
return render(request, "load.html")
# The user is just loading the view for the first time (GET)
return render(request, "index.html")
I highly suggest going through the django tutorial.
You have to realise that Django is a HTTP based framework meaning that when an HTTP request is sent to a url, Django will be allowed to perform an action. So, every function is actually a reaction to the HTTP requests that the user sends to your urls.
Also, if you are using Django template system, the html file should be rendered by Django in the first place. So, you cannot have a standalone html file with {% url my_view %} in it.
First, you have to configure the main urls.py which is in a folder with the same name as your project.
Second, in your app, create an urls.py file and configure it.
At the end, you connect your my_view to a specific or set of urls and will be triggered when a request is sent to that url, whether GET or POST.
These are somewhat large (and easy) topics for which you have to watch a tutorial or read the Django documentations.

Wagail one page with different content

I am new to Wagtail and python, so could apprectiate some help with my problem.
I have a web app (wagtail web site + rest api backend).
On my website I have 2 pages:
HomePage with list of accessible objects (e.g. photos)
PhotoPage with a detailed information on photo
What I want to achive:
When I click on photo on homepage I am redirected to the photopage
I fill the photopage with information I got from backend
And the photopage url is smth like this http://example.com/photo?id=12345
So, I want to
have 1 model for photopage
fill photopage based on a requested url (i.e. from homepage I redirect user to example.com/photo?id=12345 and it is filled with information on photo with id=12345)
I guess there should be some middleware to parse requested url to get the id and fill the page with info from API. Is there any standard solution to this issue?
Page objects (and any classes that inherit from Page) have a get_context method that can be used to add context pre-rendering of your templates.
from django.shortcuts import get_object_or_404
class PhotoPage(Page):
# your model definition ...
def get_context(self, request):
context = super(PhotoPage, self).get_context(request)
photo_pk = request.GET.get('id',None)
photo = get_object_or_404(YourPhotoModel,pk=photo_pk) # if no matching photo, return 404. You can do whatever you like instead :)
context['photo'] = photo
return context
Now in your photo template you can access your Photo model instance directly...
{{ photo.some_attribute }}
{{ photo.some_other_attribute }}

Categories