Multiplying inside an HTML document - python

I'm working on a web application on Google App Engine with Python as my backend language. Now, I need to calculate a particular value based on the user input and display it on my web page. Here's the concerned code sample:
<h4>Total Amount:{{disp.actual_price}}*{{quantity}}</h4>
Now I'm using Jinja 2 template for rendering my HTML pages. In the above example, 'disp.actual_price' is the value of the 'actual_price' attribute in my 'disp' entity of my Google App Engine datastore, while 'quantity' is a value passed on by the user. So basically, I'm unable to figure out a way to multiply these two variable values and displaying them on the webpage. If the actual_price is 300, and the value of 'quantity' is 2, then here's what gets displayed with my above code:
Total Amount:300*2

You should write it this way:
<h4>Total Amount:{{disp.actual_price * quantity}}</h4>

The correct answer to the question is don't do it. I'll explain why in a moment.
The correct syntax to do what you are attempting to do is:
<h4>Total Amount:{{disp.actual_price*quantity}}</h4>
From the documentation
There are two kinds of delimiters. {% ... %} and {{ ... }}. The first one is used to execute statements such as for-loops or assign values, the latter prints the result of the expression to the template.
In this particular case, either delimter would work fine. But you'd really want to use the second one. Your code didn't work because anything outside of the delimiter is treated as plain HTML. It has to be inside the delimiter to be treated as an expression.
But why is this wrong? You are mixing business logic with interface. Doing this means that the day you want to change the design of the page, or the workflow, you'll be juggling around business variables in the page. If the calculation got a little more complex, then your template does too. But worst of all, if you move to a different templating engine, then your entire application is screwed because all your business logic is stuffed inside the template.
To do this correctly you need to have a file that just does the calculations by itself. In your file where you have the template being called, you should import this logic file and call on the methods inside it. Thus, the method inside the file responding to the HTTP requests, might look like this:
#initialize template variable
totalAmount = importedLogicModule.calculateTotalAmount(disp.actual_price, quantity)
return template.render(totalAmount = totalAmount)
and the template would now be
<h4>Total Amount:{{totalAmount}}</h4>

Related

Web2Py Multiple Smartgrids in a view

I am trying to build a view in web2py that has multiple smartgrid objects served from the same controller. It displays them absolutely fine, but whenever I try to create a new record on the second table it doesn't allow entry, it just seems to refresh the page. Also trying to search on the second table actually fills in the search field on the first table too, so there is obviously some confusion as to which smartgrid is which.
In my research I came across the multiple form technique using process to name each form, see below:
form1.process(formname='form1')
However, this methodology doesn't seem to work for smartgrid objects (as far as I can tell). I guess I could try to create my own new SQLFORM.grid, but it seems a shame that I can't make better use of the smartgrids, as they have everything I need already.
Any help appreciated.
As you have noted, you cannot have two grids on the same page in this manner, as the grid makes use of the URL to determine its current state. Instead of the iframe approach, though, you might consider putting each grid in an Ajax component. In the main view file:
{{=LOAD('default', 'grid1.load', ajax=True)}}
{{=LOAD('default', 'grid2.load', ajax=True)}}
Of course, you can also serve both grids from the same action by specifying a URL arg to differentiate them.
To allow the grid machinery to deal with generated URLs like
/app/default/grid1.load/view/record/1?_signature=88ce76119afc68bbb141fce098cbc2eaf39289e3
for a view of a single record,
you must identify grids uniquely.
So construct your grids with formname keyword. Example:
def manage_records():
q_record = (db.record.au==auth.user_id)
return dict(record = SQLFORM.grid(q_record, formname='records'))
def manage_reports():
q_report = (db.report.au==auth.user_id)
return dict(record = SQLFORM.grid(q_report, formname='reports'))
Just as Antony have pointed, you can use LOAD() functionality.
You can omit ajax=True, if you want forms will load with a main page.
In the view with two grids:
<h2>Reports</h2>
{{=LOAD('default', 'manage_reports.load')}}
<h2>Records</h2>
{{=LOAD('default', 'manage_records.load')}}

Django: how to transfer scattered data to a template?

Introduction
In Django, when the data you want to display on a template is included in one object, It's f**** easy. To sum up the steps (that everyone knows actually):
You Write the right method to get your object in your model class
You Call this method in your view, passing the result to the template
You Iterate on the result in the template with a for loop, to display your objects in a table, for example.
Now, let's take a more complex situation
Let's say that the data you want to display is widely spread over different objects of different classes. You need to call many methods to get these data.
Once you call these different methods, you got different variables (unsimilar objects, integers, list of strings, etc.)
Nevertheless, you still want to pass everything to a template and display a pretty table in the end.
The problem is:
If you're passing all the raw objects containing the data you need to your template, it is completely unorganised and you can't iterate on variables in a clean way to get what you need to display your table.
The question is:
How (which structure) and where (models? views?) should I organize my complex data before passing it to a template?
My idea on this (which can be totally wrong):
For each view that need "spread data" to pass to a template, I could create a method (like viewXXX_organize_data()) in views.py, that would take the raws objects and would return a data structure with organized data that would help me to display a table by iterating on it.
About the data structure to choose, I compared lists with dictionaries
dictionaries have key so it's cleaner to call {{dict.a-key-name}} rather than {{ tabl.3}} in the template.
lists can be sorted, so when you need to sort by date the elements you want to display, dictionary is not helpful, arghh, stuck again!
What do you think about all that? Thanks for reading until there, and sharing on this!
With your question you are entering in a conceptual/architectural domain rather than in a "this particular view of the data in my project is hard to represent in the template layer of django". So I will try to give you the birds view (when flying and not on the ground) of the problem and you can decide for yourself.
From the first philosophy box in the django template language documentation it's clearly stated that templates should have as little program logic as possible. This indicates that the representation of the data used in the template should be simple and totally adapted to the template you are trying to build (this is my interpretation of it). This approach indicates that you should have a layer responsible for intermediating the representation of your data (models or other sources) and the data that your template needs to achieve the final representation you want you users to see.
This layer can simple stay in your view, in viewXXX_organize_data, or in some other form respecting to a more complex/elaborated architecture (see DCI or Hexagonal).
In your case I would start by doing something like viewXXX_organize_data() where I would use the most appropriate data structures for the template you are trying to build, while keeping some independence from the way you obtain your data (through models other services etc).
You can even think of not using you model objects directly in the template and creating template specific objects to represent a certain view of the data.
Hope this helps you make a decision. It's not a concrete answer but will help you for sure make a decision and then staying coherent all trough your app.

google app engine textarea (from form) to datastore

So i have a simple form that takes a few inputs (two text and two textareas) and runs it through a function that puts all four inputs into the datastore (google app engine). The problem is when I have a decent amount of text in one of the s (meaning, 5 paragraphs, ~4/5 sentences each, ..2,000 characters).
I am using TextProperty() s in the datastore, (and also StringProperty for the smaller inputs). It works when I only put in like a few words for each, but not when I put in a decent amount of text, what happens: a blank webpage comes up instead of my basic confirmation page. No data is transferred into the datastore.
My handler uses get() (as opposed to POST)
Why is this happening and how do I fix it?
I'm sure this is a simple fix, but I am somewhat green to this. Thanks
While in theory there is no limit, in practice all the browsers apply some limits to the query string and since you are using GET instead of POST all your inputs are passed as query parameters in the URL.
When you are getting values from input forms, you should use the proper method="POST" in the <form> and handle that correctly in your handler using post(). If you go through the Getting Started you will find out the section for Handling Forms.

App Engine - Output Response Time

Say I wanted to print the response time on my pages like Google do.
How would I go about doing this?
Call start = time.time() as the very first operation in your handling scripts, and, when you're just about done with everything, as the very last thing you output use (a properly formatted version of) time.time() - start.
If you're using templates for your output (e.g., the Django templates that come with app engine -- 0.96 by default, though you can explicitly ask for newer and better ones;-), or jinja2, mako, ...), it's important to be able to use in those templates a tag or filter to request and format such an expression. (You don't want to compute it at the time you call the template's render method, and pass it as part of that method's context, or else you'll fail to account for all the template rendering time in your estimate of "response time"!-). You may have to code and inject such a tag or filter into the "templating language" if your chosen templating language and version doesn't already supply one but is at least minimally extensible;-).
`

GAE/Django Templates (0.96) filters to get LENGTH of GqlQuery and filter it

I pass the query with comments to my template:
COMM = CommentModel.gql("ORDER BY created")
doRender(self,CP.template,{'CP':CP,'COMM':COMM, 'authorize':authorize()})
And I want to output the number of comments as a result, and I try to do things like that:
{{ COMM|length }} comments
Thats does not work (yeah, since COMM is GqlQuery, not a list). What can I do with that? Is there a way to convert GqlQuery to list or is there another solution? (first question)[1]
Second question [2] is, how to filter this list in template? Is there a construct like this:
{{ COMM|where(reference=smth)|length }} comments
so that I can get not only the number of all comments, but only comments with certain db.ReferenceProperty() property, for example.
Last question [3]: is it weird to do such things using templates?
UPD: Questions [1] and [3] are pretty much clear to me, thanks to Nick Johnson and Alex Martelli.
Question [2] is tricky and maybe against the idea of MVC, but I really hope to solve it with templates only :(there are some reasons). It may be as ugly as it gets.
Call .fetch() on the query, returning a list of results, before passing it to the template. Any other solution - such as calling .count() - will result in executing the query multiple times, which wastes CPU and wall-clock time.
Likewise, if you need to filter the query, you should do this in your own code, before passing the results to the template system.
You could use count on your GqlQuery object, but a GqlQuery doesn't let you add where clauses and the like -- you need Query for that (and its filter method).
Yes, it's very unusual to "pollute" the view logic (i.e., templates) with business logic aspects such as filtering. Normally, the server-side Python code would perform such calls and inject the results in the context, leaving the view logic (template) to deal strictly with presentation issues only -- server side decides what to show, view logic decides only how to show it.
If you prefer a less usual style, with lots of logic in the templates (an architecture that many do consider weird), consider alternative templating systems such as Mako, because the Django templating system is really designed against such "weird architecture";-).
I'm not exactly sure what your trying to accomplish, but you could possibly benefit from URL Mapping, however it will require some extra code. The basic idea is that you would turn whatever value you want to filter against into a "directory". Examples will help:
link text
Then in your python code you would need modify your WSGIApplication object with a unique handler. Something like:
application = WSGIApplication(
[('/', MainPage),
(r'/basepath/(.*)', Products),
Just create a new class called Products, and it will automatically pick up the filter value and store it in a variable for you, like so:
class Products(webapp.RequestHandler):
def get(self, ProductID):
And thats it, you can expand this as much as you want, add more levels. In the class Products you would just filter your Query object using the ProductID variable as your criteria.
I have a more in depth write up at my Blog if you want to read more on this.

Categories

Resources