Trigger view function with bootstrap button - django

I don't really get how to make a button click trigger my view function... I already googled, but nothing really helps me understand...
In my html, I have:
<a class="btn btn-large btn-info" href="{% url "device-detail" device.pk %}" name = 'rotateleft'>Rotate Left</a>
And in my views.py:
class DeviceDetail(DetailView):
....
def rotate_left(request, self):
if request.GET.get('rotateleft') == 'rotateleft':
print 'TEST!!!!'
self.image.open()
self.image.rotate(-90)
self.image.save()
If I click the button, the page seems to be reloaded as planned, but as 'TEST' is not printed (and the image is not rotated, but it might be that the code that is supposed to rotate it doesn't work yet, I wanted to call the function to see if it works), I'm guessing that this function is never called.
I am relatively new to Django and very new to the web interface side of Django, so help would be really appreciated!

You seem to be confusing a few things here. Clicking the link will "refresh" the DeviceDetail page as you noticed. Adding a name attribute on your HTML link won't however affect the request made to the server.
Based on what you are trying to accomplish it seems you should use a simple view function and perhaps read in a a GET parameter for deciding which way to rotate your image. Note that the parameters you pass to your view needs to be within the link URL, like:
href="{% url "device-detail" device.pk %}?rotate=right"

Related

Passing HTML code as string variable to template for PDF generation

I'm working on a Django app which parses xlsx input, processes series of REST API queries and returns the result of the queries as a table in one of my django templates. The HTML code containing the results table is generated with Pandas.to_html() functionality. The HTML code is stored in a variable ("table") and passed to the html template, where it is displayed as {{ table | safe }}. This mechanism works just fine. However, I'm now struggling to add a button which would generate a pdf file to be downloaded by the user.
NOTE: I'm aware it would probably make more sense to use JS to render the PDF on the client side, but at the moment the point is to avoid doing so.
Upon some research, I decided to go with the django-easy-pdf library. I based my solution on the example included in the documentation, but so far to no avail.
In urls.py:
urlpatterns = [
[...]
path('result.pdf', views.PDFView.as_view(), name='PDFview'),
]
In views.py:
class PDFView(PDFTemplateView):
template_name = 'whitelist/listresult.html'
table = None
def get_context_data(self, **kwargs):
return super(PDFView, self).get_context_data(pagesize='A4', title='Hi there!', table=self.table, date=date.today)
Please note that the template "listresult.html" is the one expecting the {{ table }} variable.
Last but not least, in the very listresult.html (where I want to place the button to render the PDF file), I added a simple button object:
<a class="btn btn-secondary btn-lg" href="{% url 'PDFview' table %}">Download PDF</a>
My expectation was that since I'm sending the "table" variable along with the request for PDF url, the view would process it nicely and prompt the user with a download pop-up for the PDF file looking exactly (or almost exactly) as the page which presented the result in the first place. However, I'm cought in a vicious circle where if I add "table" to the url reference on the site I get an error during template rendering for the very website displaying results (NoReverseMatch for ..., Reverse for 'PDFview' with arguments '['table' contents go here] not found). On the other hand, if I remove the "table" argument from the url reference, the results website renders OK with the "Download PDF" button, but upon clicking it I'm left with a Runtime Error (since context is missing).
I'm 97% confident my mistake is ostentatiously stupid, but after x hours of struggle I'm ready for StackOverflow's judgement.

Django: use POST or links, which is better practice?

A noobish question to be sure.
<a href="{% url 'stuff.views.SomeView' %}/somethingnew">
<button>See something new on this page</button>
</a>
<form action="" method="post">{% csrf_token %}
<button name="somethingnew" type="submit" value=True>See something new on this page</button>
</form>
With either choice, I update some boolean variable, perform the appropriate calculations, call the page view and render a page with something new on this page. Part of the reason I use either method is to save the state of a collection of boolean variables. What is the best way 1) change a boolean variable 2) save its state 3) perform the necessary updates when the button is clicked and finally 4) render page after the underlying data has been updated?
Right now, I am using forms rather than links so that I don't need to code a url for each boolean variable. Which method is better? Will one method improve the time it takes to reload the page (assuming many boolean variables)?
1) Following the REST mindset, a POST request is in order to transmit the user input, since you are altering database objects.
2) I'd save it in the Session object if the input is not needed forever (session duration). Otherwise in the database as you are doing now.
3/4) I'd gather all the necessary info in a form. When the user commits the form in a POST request, I'd compute the data and respond with the rendered page containing the computed result. If the input variables are gathered step by step with intermittent computation, I'd just update the input form accordingly (display different choices in a combo box or something like that). Of course the transmitting could be done in an AJAXy way, too.

tag url template django doesn't work

I trying to implement the url template tag into my project.
I have a button that allows the user to save the data he is seeing.
So the url of this button is this:
(2)url(r'^nameviews/download/$', 'my.path.is.this.to.download' name="load"),
template:
Download
the url of the page that shows the information, and where the button is located is:
(1)(r'^nameviews/$', path.to.page),
but when I tried to click on the button (it should appear the url 2)it doesn't open the file with the data but instead gives me the same url that the main page (1)
the html validator gives me a error on the
<a href="">
It seems it doesn't recognize the url tag.
Anyone has any idea?
Resolved! I didn't really understood what's happen because I didn't change much but should have been some silly mistake.
Sorry!
Thanks any way :)
EDIT
Be careful with the order of the urls. At urls.py try this order:
url(r'^nameviews/download/$', name_of_view, name="load"),
url(r'^nameviews/$', name_of_view, name="first page"),
name_of_view is equal if the view is the same

Adding an extra button to one object in django admin

I hope this hasn't been asked and I just missed it, but I searched a bunch and couldn't find anything.
I'm adding an extra save button to the django admin when adding or changing an object. Doing that is fairly easy. I just overrode the submit_line.html to add the extra button and then overrode the save_model function to check for the name of that button. It works great.
My problem is that I only need this button to appear for one particular object... not all of them. I looked in change_form.html to see how it knows what object it is dealing with and found {{ opts.module_name }}, but it doesn't seem to be accessible in submit_line.html. I tried printing it out and nothing showed up.
I also thought about hacking save_as (not very graceful, but I don't really care for this particular project), but that button only shows up on change.. not on add, so that won't work.
Does anyone know how to detect what object I'm working with in submit_line.html? Or any other way of doing this?
Thanks!
You can do it using javascript like this:
/static/js/useful.js
$(document).ready(function ($) {
$('input[name="_addanother"]').before('<input type="submit" name="_use" value="Useful functionality"/>');
});
and in your ModelAdmin add:
class MyModelAdmin(admin.ModelAdmin):
class Media:
js = ('/static/js/useful.js',)
You should be able to access the original object in change_view's context through original. For example {{ original.id }} should print its id!

Django: How do I position a page when using Django templates

I have a web page where the user enters some data and then clicks a submit button. I process the data and then use the same Django template to display the original data, the submit button, and the results. When I am using the Django template to display results, I would like the page to be automatically scrolled down to the part of the page where the results begin. This allows the user to scroll back up the page if she wants to change her original data and click submit again. Hopefully, there's some simple way of doing this that I can't see at the moment.
It should already work if you provide a fragment identifier in the action method of the form:
<form method="post" action="/your/url#results">
<!-- ... -->
</form>
and somewhere below the form, where you want to show the results:
<div id="results">
<!-- your results here -->
</div>
This should make the page jump to the <div> with ID results.
It is complete client site and does not involve Django, JavaScript or similar.
You need to wrap your data into something like this:
<div id="some-id">YOUR DATA TO BE DISPLAYED</div>
and if you make redirect in your view you need to redirect to url: /some-url/#some-id
if you don't make redirect you need to scroll to the bottom using javascript (but note that redirect is preffered way to use in view after saving data).