SqlAlchemy query in a template page - python

I have a query like this:
session.query(System).filter_by(id_system = s.id_system).join(Command).filter_by(id_command=c.id_command).first()
I'd like to do this query in a template page (I'm using mako), but it doesn't work:
% for c in s.commands:
code = session.query(System).filter....
% endfor
What is best way to do a query in pages? Or is it not possible?

Template is not a right place to do such operations. All business logic needs to be included into controllers according to MVC (or RV as Pyramid) paradigm.
Do query in your view function:
results = DBSession.query(model.Articles).all()
return dict(status=True, results=results)
or even better create module which contains common database operations (then import function and call it in view function) and return results to template by
import your_project.lib.dbfunctions
results = dbfunctions.get_articles()
return dict(status=True, results=results)
than use them into template:
<div>
% for r in results:
${r}
% endfor
</div>
I hope it will help you.

While it may be possible by injecting the session and other needed functions into the template context, this is not the right way to do things. The data, for the most part, should be handled outside the template, then passed to the context when rendering.
The view/function that is calling render for this template should be making this query and passing it to the template.

Related

Render dynamic value inside content django template

Please, I would like to render a varible in django template, kind of {{ user.name }} inside of a textfield from database, that I filled up on the django admin. like this
how can I manage to achieve it please, thank you all, have a good day.
If you are using custom form then try using
value={{ user.name }}
and if you are letting Django render the form for you as like "form.as_p" then you can try
form_instance = Form(request.POST)
and send the form instance to the template
After a while of looking, I found out that the right solution of accomplishing such a thing is by creating a filter or tag and affecting it to the content rendered from the database based on the Django documentation link to create custom filters and tags, I created a filter that takes the content as a variable and scanned whenever I find the variable I replace it with the content from the database
# This code goes in the filter logic
values = model.objects.all()
content.replace('{{ user.name }}',values.name)
# This is how the content is rendered on the template
{{content | filter_name}}

How can I pass a client-side parameter to a server-side route without using forms?

I have a simple Flask web app. My index template has various ways of interacting with clients using javascript and HTML. I am also have a form that, upon submission, routes to another flask process and uses the request.form command to retrieve user-submitted data.
However, I want to do something a little different. I would like to initiate a Flask redirection upon javascript event but include a parameter, and not use form.
For example, my index.html file would display something like this after template rendering:
function startRedirect(parameter) {
window.location.pathname = '/myRedirect';
}
<input type="checkbox" id="sample" name="sample" onChange="startRedirect(parameter);">
And part of my Flask script would have:
#app.route('/myRedirect')
def myRedirectFunction():
# do something with the parameter here
return render_template('index.html')
I realize this can be done with using a form, but I am interested in accomplishing this task without having a form. I was thinking about somehow using request.args, but don't quite understand what to do.
You can use a dynamic route to capture a simple input and pass it to the route's function.
app.route('/myRedirect/<param>')
def myRedirectFunction(param='hello world'):
return render_template('index.html', param=param)
Using this route as a redirect, you can pass a single param (or multiple if you serialize them) that you can use to do something. From there, you can either display or you can redirect again to a common endpoint so the user does not see the param in the url.
There's no need for a form or an explicit redirect, just attach a route and some parameter to the dynamic route.
Let's say you have a model to list the departments in your company:
class Departments(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
Now you have a department selection page:
#app.route('/departments_home', methods=['GET'])
def departments_home():
departments = Departments.query.all()
return render_template('departments_home.html',
departments=departments)
On the frontend you might have a variety of selections, each giving a link to the same route but with a different department_id:
{% for department in departments %}
Click to go to {{ department.name }}
{% endfor %}
Now you just need another route to handle this, taking the variable department_id that was passed in the GET request:
#app.route('/load_department/<department_id>', methods=['GET'])
def load_department(department_id):
department = Departments.query.get(int(department_id))
department_data = # do stuff here with the specific department

Include a menu to several templates in Django

I'm trying NOT to write same code twice on different templates. Real hassle when changing something.
So when I go to a section of the webpage, I want to display a side menu. This side-menu is suppose to be on several templates. Like index.html, detail.html, manage.html and so on.
But the section is only a part of the webpage, so I can't have it in base.html.
I was thinking about using include. But since the side menu is dependent of DB queries to be generated, I then have to do queries for each view. Which also makes redundant code.
What is best practice for this feature?
Cheers!
You could write custom inclusion_tag, that's more feasible for the scenario:
my_app/templatetags/my_app_tags.py
from django import template
register = template.Library()
#register.inclusion_tag('side_menu.html')
def side_menu(*args, **kwargs):
# prepare context here for `side_menu.html`
ctx = {}
return ctx
Then in any template you want to include side menu do this:
{% load side_menu from my_app_tags %}
{% side_menu %}

Django Haystack - Show results without needing a search query?

I would like to display all results which match selected facets even though a search query has not been inserted. Similar to how some shop applications work e.g. Amazon
e.g. Show all products which are "blue" and between $10-$100.
Haystack does not return any values if a search query is not specified.
Any ideas how I can get around it?
Thanks!
If anyone is still looking, there's a simple solution suggested in haystack code:
https://github.com/toastdriven/django-haystack/blob/master/haystack/forms.py#L34
class SearchForm(forms.Form):
def no_query_found(self):
"""
Determines the behavior when no query was found.
By default, no results are returned (``EmptySearchQuerySet``).
Should you want to show all results, override this method in your
own ``SearchForm`` subclass and do ``return self.searchqueryset.all()``.
"""
return EmptySearchQuerySet()
Why No Results?
I imagine you're using a search template similar to the one in the haystack getting started documentation. This view doesn't display anything if there is no query:
{% if query %}
{# Display the results #}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
The second problem is that the default search form's search() method doesn't actually search for anything unless there's a query.
Getting Results
To get around this, I'm using a custom search form. Here's an abbreviated sample:
class CustomSearchForm(SearchForm):
...
def search(self):
# First, store the SearchQuerySet received from other processing.
sqs = super(CustomSearchForm, self).search()
if not self.is_valid():
return sqs
filts = []
# Check to see if a start_date was chosen.
if self.cleaned_data['start_date']:
filts.append(SQ(created_date__gte=self.cleaned_data['start_date']))
# Check to see if an end_date was chosen.
if self.cleaned_data['end_date']:
filts.append(SQ(created_date__lte=self.cleaned_data['end_date']))
# Etc., for any other things you add
# If we started without a query, we'd have no search
# results (which is fine, normally). However, if we
# had no query but we DID have other parameters, then
# we'd like to filter starting from everything rather
# than nothing (i.e., q='' and tags='bear' should
# return everything with a tag 'bear'.)
if len(filts) > 0 and not self.cleaned_data['q']:
sqs = SearchQuerySet().order_by('-created_date')
# Apply the filters
for filt in filts:
sqs = sqs.filter(filt)
return sqs
Also, don't forget to change the view:
{% if query or page.object_list %}
{# Display the results #}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
Actually, the view code is a little hackish. It doesn't distinguish query-less searches with no results from search with no parameters.
Cheers!
Look at SearchQuerySet.
This should be possible if color and price has been defined in your SearchIndex:
sqs = SearchQuerySet().filter(color="blue", price__range=(10,100))
You can limit the query to certain models by adding models(Model) to the SearchQuerySet. So if you want to limit your query to the model Item use:
sqs = SearchQuerySet().filter(color="blue", price__range=(10,100)).models(Item)
Following form display all the result if not query string is present. Now you can add custom filters.
from your_app.forms import NonEmptySearchForm
url(r'^your_url$',
SearchView(template='search.html',searchqueryset=sqs,form_class=NonEmptySearchForm), name='haystack_search'),
forms.py
#Overridding because the default sqs is always none if no query string is present
class NonEmptySearchForm(SearchForm):
def search(self):
if not self.is_valid():
return self.no_query_found()
sqs = self.searchqueryset.auto_query(self.cleaned_data['q'])
if self.load_all:
sqs = sqs.load_all()
return sqs
Stumpy Joe Pete's answer is pretty spot on, but as he mentioned, the template if query or page.object_list check is a little hacked. A better way of solving this would be to create your own SearchForm which would still find something if q is empty - will not repost that - AND to customize the SearchView with something like:
class MySearchView(SearchView):
def get_query(self):
query = []
if self.form.is_valid():
for field in self.form:
if field.name in self.form.cleaned_data and self.form.cleaned_data[field.name]:
query.append(field.name+'='+str(self.form.cleaned_data[field.name]))
return ' AND '.join(query)
In most cases, you won't even be using the query value, so you could just as well do a quick check if any of the fields is set and return True or something like that.. or of course you can modify the output any way you want (I'm not even 100% sure my solution would work for all field types, but you get the idea).

Django: Template composed of Templates

In one of my Django templates, I have a chunk of HTML which repeats at several places in the page. Is there a way I could use another template for this chunk alone and "instantiate" the template where required?
You need to read about template inheritance.
Or you can use template composition.
Inheritance is, generally, a better way to go.
I've met the same issue some time ago and here is what I got.
Seems like it's not really well documented, but there is quite obvious solution - insert HTML blocks in your main template and then pass the result of the other template render there.
Example:
In main template (app/main.html):
<!-- ... -->
{% autoescape on %}
{{html}}
{% autoescape off %}
<!-- ... -->
In view code:
from django.template.loader import get_template
def my_view(request, ...):
# Do stuff...
context = {'data': 'data'}
t = get_template('app/partial_template.html')
html = t.render(context=context)
return render(request, 'app/main.html', context={'html': html, 'rest_data': 123})
Thus you'll get some template rendered inside another template with perfect separation of concerns (parent template doesn't know anything about child's context nor about child itself).

Categories

Resources