In which variable is the model instance stored in customized view? - flask

How can I actually pick up values from my model in a customised template?
Let's assume for this example, the model for Request has an attribute "title".
Following views.py:
class RequestModelView(ModelView):
datamodel = SQLAInterface(Request)
extra_args = {'my_extra_arg':Request}
show_template = 'show_request.html'
list_columns = ['title','description','request_status']
and here the show_requests.html
{% extends "appbuilder/general/model/show.html" %}
{% block show_form %}
This Text is before the show widget
{{ super() }}
This Text is shown below..
<hr>
{{ (self.title) }}; {{pk}}; {{pk['title']}}
{% endblock %}
In which variable can I find my object?
The only parameter that works is {{pk}} (it shows the ID of the Request).
I was thinking of something like item['title']
Thanks.

A very similar question was asked on their Github. I think you would have to use something along these lines:
views.py
class RequestModelView(ModelView):
datamodel = SQLAInterface(Request)
list_columns = ['title','description','request_status']
add_template = 'show_request.html'
#expose('/show_request', methods=['GET', 'POST'])
#has_access
def show_request(self):
get_filter_args(self._filters)
self.extra_args = {'item': list_columns}
return super(RequestModelView, self).add()
show_requests.html:
{% extends "appbuilder/general/model/show.html" %}
{% block show_form %}
This Text is before the show widget
{{ super() }}
This Text is shown below..
<hr>
{{ item['title'] }}
{% endblock %}
Documentation is certainly not very clear in this aspect, but please check template-extra-arguments
I'm not sure if you would still need extra_args = {'my_extra_arg':Request}.

The following example should make things clear:
from .models import cars
beautiful_names = ["John", "Jane", "Bob"]
flowers = ["Aster", "Buttercup", "Roses"]
class IndexView(View):
template_name = "dashboard/dashboard_index.html"
def get(self, request, *args, **kwargs):
all_car_objects=cars.objects.all()
return render(request,
self.template_name,
context={"my_addresslist": beautiful_names,
"my_rose_list": roses},
"all_cars":all_car_objects)
In your template you can then do something like:
<h1>Beautiful Names</h1>
{% for name in my_addresslist %}
<p>{{ name }}</p>
{% endfor %}
<h1>Roses</>
{% if my_rose_list %}
{% for rose in my_rose_list %}
<p>{{ rose }}</p>
{% endfor %}
{% endif %}
<h1>Cars</>
{% if all_cars %}
{% for car in all_cars %}
<div>
<p>{{ car.name }}</p>
<p>{{ car.make }}</p>
<p>{{ car.model }}</p>
</div
{% endfor %}
{% endif %}
So for your example, it comes down to this:
class MyView(ModelView):
datamodel = SQLAInterface(MyTable)
extra_args = {'my_request_list':Request}
show_template = 'show_request.html'
<h1>Requests</>
{% if my_request_list %}
{% for request in my_request_list %}
<p>{{ request }}</p>
{% endfor %}
{% endif %}

Related

I want to display User videos and Other's videos separately. I am not getting output from the following code, Is my approach correct?

My view goes something like this
class Test(ListView):
model = VideoUpload
template_name = 'videoTube/videoTube.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["my_video_list"] = VideoUpload.objects.filter(user=self.request.user)
context["other_video_list"] = VideoUpload.objects.exclude(user=self.request.user)
print(context)
return context
Template code
{% for vid in my_video_list %}
{% if forloop.counter < 5 %}
{{ vid.video }}
{% endif %}
{% endfor %}
{% for vid in other_video_list %}
{% if forloop.counter < 5 %}
{{ vid.video }}
{% endif %}
{% endfor %}
I am not getting anything in the output. I am expecting my_video_list and other_video_list should be displayed separately

Django inclusion_tag contents not displaying

I cannot get the contents of an inclusion_tag to display. I am not getting an errors so i know that the tag is registering and I am almost certain that it is loading correctly. The tag is created in crudapp/templatetags/crudapp_tags.py
from django import template
register = template.Library()
#register.inclusion_tag("forum.html")
def results(poll):
form = 'blah'
return {'form': form}
templates/forum.html
{% extends 'index.html' %}
{% load crudapp_tags %}
{% results poll %}
<p>aaa</p>
{% block homepage %}
<p>bbb</p> <!-- Only this displays -->
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
<div>
<p>{% if user.is_authenticated %}Add a New Topic: <span class="glyphicon glyphicon-plus"></span>{% endif %}</p>
</div>
<div>
<p>{{ totalposts.count }} posts, {{ totaltopics.count }} topics, {{ totalusers.count }} users, {{ totalviews.numviews}} views</p>
</div>
{% endblock %}
The file set up is as follows,
If you are using an inclusion tag, then the tag renders another template. You need to move the code that uses form out of forum.html and into a new template, e.g. results.html
results.html
{% if form %}
<p>Form exists</p>
{% endif %}
{% for item in form %}
<p>This is {{ item }}</p>
{% endfor %}
Then change your tag to use this template
#register.inclusion_tag("results.html")
def results(poll):
form = 'blah'
return {'form': form}
Finally, since you are extending a template, you need to move then tag into a block, otherwise the result won't be used.
{% block homepage %}
{% results poll %}
...
{% endblock %}
If you want to add an item to the template context instead of rendering another template, then you want a simple tag instead.
#register.simple_tag
def fetch_result():
result = ['foo', 'bar']
return result
Then in your template:
{% fetch_result as result %}
{% for item in result %}
<p>This is {{ item }}</p>
{% endfor %}
The {% fetch_result as result %} works for simple tags in Django 1.9+. In earlier versions, you want an assignment tag.

Flask/Jinja2 form submit button not working

I've got a simple form where a user enters two dates. My input is getting passed correctly, but the Submit button isn't working. Here's my view:
# GLASS ------------------------------------------------------------------------
class NameForm(Form):
starts_on = StringField('Starts', validators=[Required()])
ends_on = StringField('Ends', validators=[Required()])
submit = SubmitField('Go')
#app.route('/glass/', methods = ['GET', 'POST'])
def glasses():
starts_on = None
ends_on = None
results = None
form = NameForm()
if form.validate_on_submit():
starts_on = form.starts_on.data
ends_on = form.ends_on.data
# SQL takes starts_on, and ends_on as inputs
results, start_date, end_date, companies_tracked = diagUserActs.userTime(starts_on, ends_on, diagUserActs.companies)
form.starts_on.data = ''
form.ends_on.data = ''
return render_template('glass.html', form = form, results = results)
And here's my template:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
<!--{% block title %}Glasses{% endblock %}-->
{% block content %}
<form class="form-inline" method="post" role="form">
{{ wtf.form_field(form.starts_on) }}
{{ wtf.form_field(form.ends_on) }}
{{ wtf.form_field(form.submit) }}
</form>
Oddly enough, this method below works, but I'd like to list the form elements individually so I've got more control regarding its presentation:
<form class="form-inline" method="post" role="form">
{% for field in form %}
{{ field.label }}
{{ field(placeholder="YYYY-MM-DD") }}
{% endfor %}
</form>
What I've done before is use something like this:
{% macro render_field(field, class='None') %}
<div class="pure-control-group">
{{ field.label(class_=class)|safe }}
{{ field(class_=class)|safe }}
{% if field.errors %}
<p class="errors">
{% for error in field.errors %}
<p>
{{ error }}
</p>
{% endfor %}
</p>
{% endif %}
</div>
{% endmacro %}
Then use it something like this:
{{ render_field(form.username) }}
Where form is something like this:
form = forms.Login(request.form)
It seems there is something wrong with the form here:
{{ wtf.form_field(form.starts_on) }}
I've never seen it used that way.

Django Reverse Query in Template

I have models like this
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def __unicode__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
I want to list all blogs in a page. I have written a view such that
def listAllBlogs(request):
blogs= Blog.objects.all()
return object_list(
request,
blogs,
template_object_name = "blog",
allow_empty = True,
)
And I can display tagline of blog such that in view
{% extends "base.html" %}
{% block title %}{% endblock %}
{% block extrahead %}
{% endblock %}
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% endfor %}
{% endblock %}
But I would like to show, such thing blog__entry__name but I don't know how can I achive this in template.
Also, there may be no entry in a blog. How can I detect in template ?
Thanks
To access blog entries (Related Manager): blog.entry_set.all
To do other actions if blog have no entries, you have the {% empty %} tag that is executed when the set is empty.
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% for entry in blog.entry_set.all %}
{{entry.name}}
{% empty %}
<!-- no entries -->
{% endfor %}
{% endfor %}
{% endblock %}
based on your code you could do the following.
{% block content %}
{% for blog in blog_list %}
{{ blog.tagline }}
{% for entry in blog.entry_set.all %}
{{entry.name}}
{% endfor %}
{% endfor %}
{% endblock %}

Object not iterable with django's pagination

I have a template showing a list of events. To prepare list of events I'm using generic views, and set 'paginate_by' parameter. Strangely when I load my page I see :
TemplateSyntaxError at /event/latest/
Caught an exception while rendering: 'int' object is not iterable
in 9th line of pagination.html template :
{% if is_paginated %}
{% load i18n %}
<div class="pagination">
{% if page_obj.has_previous %}
<< Prev
{% else %}
<span class="disabled prev"><< Prev</span>
{% endif %}
#here {% for page in pages %}
{% if page %}
{% ifequal page page_obj.number %}
<span class="current page">{{ page }}</span>
{% else %}
{{ page }}
{% endifequal %}
{% else %}
...
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
Next >>
{% else %}
<span class="disabled next">Next >></span>
{% endif %}
</div>
{% endif %}
Here is my view :
def events_nearest(request):
events = Event.nearest.all()
return object_list(request,
queryset = events,
extra_context = {'title': 'Nearest events'},
paginate_by = 12,
template_name = 'event/events_date.html')
And model :
class NearestManager(models.Manager):
def get_query_set(self):
return super(NearestManager, self).get_query_set().order_by('-data')
class Event(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=120)
slug = models.SlugField(max_length=255, unique=True, verbose_name='Slug')
about = models.TextField()
city = models.ForeignKey(City)
objects = models.Manager()
nearest = NearestManager()
Any ideas what can cause this ?
pages variable is the number of pages, which is int and hence the error: 'int' object is not iterable
you should be looping over page_range
{% for page in page_range %}
I met the same error. There is a note at
https://docs.djangoproject.com/en/dev/topics/pagination/
Changed in Django Development version: Previously, you would need to use {% for contact in contacts.object_list %}, since the Page object was not iterable.
So {% for page in pages.object_list %} could probably solve your problem.
For anybody stumbled upon this post:
As with Django 1.4 and later (as far as I know), the iterable object for pagination is now paginator.page_range , i.e. the for loop should be
{% for page_num in paginator.page_range %}
In your error line #9 {% for page in pages %} what exactly is pages
Can't see it in your code anywhere.