I am making a web application with flask, I know for a fact that you can create variables in the python file to use in the HTML file in jinja, but how can I change the value of a variable inside the HTML?
Can I do it like this?
{{ VAR_NAME == NEW_VAR_VALUE }}
help would be appreciated
Given a flask code like this:
#app.route('/')
def simple_page():
random_number = random.randint(1, 6)
return render_template('page.html', number=random_number)
Then you can access that variable through jinja2 like this:
<p>Random number: {{ number }}</p>
If you want to assign the variable passed from flask to another variable created in jinja2 (you wanna make a copy, I don't know) just write:
{% set new_var = number %}
Now you can use the variable new_var in the jinja2 code.
Wanna increase new_var? Do:
{% set new_var = new_var+1 %}
Related
I just want to slice a string on django in two parts, passing a caracter like "|"
Example: 2007-007134|10003L
Part 1: 2007-007134
Part 2: 10003L
I tried somethings but without success
Someone can help me?
Create a custom template tag. They are basically python code which you can execute from inside the html templates (when using defult Django templating engine).
You can read more about them here:
https://docs.djangoproject.com/en/3.1/howto/custom-template-tags/
https://www.codementor.io/#hiteshgarg14/creating-custom-template-tags-in-django-application-58wvmqm5f
I solved according Maciej Rogosz recommended:
Custom Template Tag
First: I created the folder templatetags inside of my app, after that create a empty ini.py and finally created my custom_tag.py:
from django import template
register = template.Library()
#register.filter(name='split1')
def split1(value, key):
return value.split(key)[1]
#register.filter(name='split2')
def split2(value, key):
return value.split(key)[0]
In my tamplate I have to load the template tags
{% load custom_tags %}
And call my custom_tags: split1, split2
{{ instance.mat_code|split1:"|" }}
{{ instance.mat_code|split2:"|" }}
That is it, python + django = Magic
Tks to everyone for your help
Ref1: https://www.w3schools.com/python/ref_string_split.asp
Ref2: https://www.codementor.io/#hiteshgarg14/creating-custom-template-tags-in-django-application-58wvmqm5f
Basically trying to do
{% url dynamic_url_name dynamic_parameter_name=dynamic_parameter_value %}
Tried the simplest approach of
{{entry}}
{% include 'mainsite/children/title_template.html' with
the_title=title_text
is_title_page=True
entries_of="title"
belongs_to="profile"
belongs_to_url_arg="user"
belongs_to_url_arg_value="author"
%}
But unfortunately this resulted in utter failure of
From this I can tell that parameters can't be context variables, so what I can try to do next is to simply unpack a dictionary as I would do inside python with something like
{% url **{dynamic_parameter_name:dynamic_parameter_value} %}
But I have no idea if it is possible inside django templates, and if possible how?
My urls look like
re_path(r'^title/(?P<title_text>[a-zA-Z0-9-]+)/$', TitlePage.as_view(), name='title')
re_path(r'^user/(?P<user>[a-zA-Z0-9-]+)/$', ProfilePage.as_view() ,name='profile')
And I the url is choosen either by a context variable or in an include tag, hence it is a variable.
{% url url_variable xxx=value %}
Now, url_variable is already a part of django, url tag accepts variable as it's first argument. But the xxx is not always the same, rather it changes according to url_variable, in this particular case; if url_variable is title, I want xxx to be title_text and if it is profile I want it to be user.
The parameter name is held in belongs_to, so if this was a regular python function, I could've simply done
url(url_variable, **{belongs_to: value})
and it would've unpacked it with the correct parameter name. So I need some kind of equivalency of this in template processor
I think you're overcomplicating things. You haven't shown your views themselves, but I can't see why they couldn't all take a commonly-named parameter - say, param - that does the specific work. So the URLs could be:
re_path(r'^title/(?P<param>[a-zA-Z0-9-]+)/$', TitlePage.as_view(), name='title')
re_path(r'^user/(?P<param>[a-zA-Z0-9-]+)/$', ProfilePage.as_view() ,name='profile')
and now you can do
{% url dynamic_url_name param=dynamic_parameter_value %}
**kwargs are not specifically supported as a parameter for the {% url %} tag, but there are a few workwarounds.
If you have a path in urlpatterns defined as:
path('myurl/<str:some>/<str:thing>', name='myurl')
Then you could have a filetoinclude.html:
My Url
And then in your main.html:
{% include 'filetoinclude.html' with urlname='myurl' some="aaa" thing="bbb" %}
And when you render you will have something like:
My Url
But obviously the issue is that maybe you want to address specific parameters of the URL when you reverse it. For this reason you could create a templatetag like:
from django.urls import reverse
from django import template
register = template.Library()
#register.simple_tag
def dynamic_url(urlname, **kwargs):
return reverse(urlname, kwargs=kwargs)
and then in your filetoinclude.html you could do:
{% load url_extended %}
{% dynamic_url urlname some=some thing=thing %}
which will yield the same URL as before.
I am creating quiz-like web application for learning languages using Flask, Jinja, WTForms, SqlAlchemy etc. Once an user completes such a language course by successfully going through all levels stored in JSON file I want the app offer him a practice mode, where the user will answer randomly selected levels.
When I run the app, I can see radio buttons generated with values from random level as I want, but when I choose any answer and submit it, form.validate_on_submit() returns False and form.errors returns {'practiceform': [u'Not a valid choice']}. When I hard-code value to currentLevel variable, it works properly.
views.py
#user_blueprint.route('/courses/<course>/quiz/practice',methods=['GET','POST'])
#login_required
def practice(course):
courseClass = class_for_name("project.models", course.capitalize())
courses = courseClass.query.filter_by(email=current_user.email).first()
maxLevel = courseClass.query.filter_by(email=current_user.email).first().get_maxLevel()
currentLevel = randint(0, maxLevel-1) # If this value is hard-coded or fetched from db, it works correctly
dic = generateQuestion(course, currentLevel)
display = dic["display"]
correct = dic["correct"]
options = dic["options"]
form = PracticeForm(request.form)
form.practiceform.choices = [(option, option) for option in options]
if form.validate_on_submit():
practiceForm = form.practiceform.data
if ((practiceForm == correct) and courses):
# Do something
flash("Nice job", 'success')
return redirect(url_for('user.practice', course=course))
else:
# Do something else
flash("Wrong answer", 'danger')
return redirect(url_for('user.practice', course=course))
return render_template('courses/practice.html', form=form, display=display)
forms.py
class PracticeForm(Form):
practiceform = RadioField('practice')
practice.html
{% extends "_base.html" %}
{% block content %}
<form action='' method='POST' role='form'>
<p>
<!-- Tried put form.csrf, form.csrf_token, form.hidden_tag() here -->
{{ form.practiceform() }}
</p>
<input type="submit" value="submit" />
</form>
{% endblock %}
So what am I missing there? What makes difference between lets say hardcoded level 25, which works properly or if the number 25 is randomly generated within randint?
My guess is that option is a int, bug WTForms get a str from request.form.
When data comes back from requests it is treated as a string by WTForms unless you specify a type explicitly with the coerce kwarg of the wtforms.fields.*Field constructor:
practiceform = RadioField('practice', coerce=int)
So I found that randint() caused the problem because the practice(course) method was called on both GET and POST actions which led to having two different integers -> two different forms most of the time. So I refactored the code. kept the practice(course) method for GET action and created a new method which handles POST action and this solved the problem.
I'm trying to write a Flask application that queries my database (using peewee), and sends the results into Jinja2 for rendering. My view looks like this:
#application.route('/maindash')
def maindash():
sq = Selfreported.select().join(Demog).where(Demog.mrn == session['mrn']).order_by(Selfreported.reportingdate)
series1data = ["Series 1", ([s.reportingdate, s.series] for s in sq)]
jsonedData = json.dumps(series1data)
return render_template('maindash.html', seriesdata=jsonedData)
To pass the results from the query into Jinja2, I know that I need to serialize the data. But when I call json.dumps: TypeError: at 0x104854be0> is not JSON serializable. So I guess I am not actually getting the data, but trying to serialize the query object itself?
Every peewee example I've looked at uses the object_list helper function from peewee-flask, rather than passing query results straight into render_template. I've looked at object_list, but I'm having a hard time understanding it --
def object_list(template_name, qr, var_name='object_list', **kwargs):
kwargs.update(
page=int(request.args.get('page', 1)),
pages=qr.count() / 20 + 1
)
kwargs[var_name] = qr.paginate(kwargs['page'])
return render_template(template_name, **kwargs)
Is there a method on a QueryResultWrapper I should be using to get the actual data rather than objects? I've looked at tuples() and dict(), but I couldn't iterate over them.
There is no reason to serialize the data before passing it to Jinja as Jinja is written in Python and can handle anything that Flask can handle. Simply pass series1data into your render_template call and walk over it in your template:
return render_template('maindash.html', seriesdata=series1data)
{# maindash.html #}
{% for reportingdate, series in seriesdata[1] %}
{{ reportingdate }} - {{ series }}<br>
{% endfor %}
I want to add a context variable in Django, so that I could define its value on per-application basis, or leave it empty.
Example:
apps/someapp/views.py:
def_context_var('app_name', 'Calendar')
templates/base.html:
{% if app_name %}You are in {{ app_name }} app.{% endif %}
....
{% if app_name %}Subsections of {{ app_name }}: ...{% endif %}
I considered the following:
Declare a variable in the app (in a view, or in URLs), and make a context processor. But I can't understang how to extract that var given the request object.
Put decorators on views. Hm, I don't like the idea: too much boilerplate or duplicated code.
#1 but nicer: make methods (like in the example above) that are executed on server restart, write the data into a dict, then a context processor somehow (how?) gets the application name and extracts the data from the dict. Where do I put the method, the dict, how does the context processor know where the view object is in?
You can call resolve(request.path) in a context processor to resolve the current url. See the django documentation on resolve for its return values, especially app_name.