I am using django to create a web app. I have run into a problem when trying to use variables from python in html. The variable does not show up. The app has a lot of messy code so I have recreated the problem including only relevant files.
views.py:
from django.shortcuts import render
# Create your views here.
def home(request):
return render(request, 'main/index.html')
def hello(request):
if request.method == 'POST':
fname = request.POST.get('fname', None)
else:
fname = "there"
return render(request, 'main/hello.html')
index.html:
{% extends "base.html" %} {% block content %}
<form action="hello" method="POST">
{% csrf_token %}
<input name="fname" placeholder="First Name">
<input type="submit" value="Submit">
</form>
{% endblock content %}
hello.html
{% extends "base.html" %} {% block content %}
<p>Hello {{fname}}</p>
{% endblock content %}
base.html:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="{% static "css/style.css" %}">
</head>
<body>
{% block content %}{% endblock content %}
</body>
</html>
Here is what the "hello" page looks like(only part of the screen):
I want it to be able to output the users input.
You can only reference a variable in a template if you include it in the "context" that is passed to the template. This is a dictionary linking variable names to the Python values they represent. The usual way to pass this to the template is as the third argument of the render method. So in your views.py, you should alter the final line to:
return render(request, 'main/hello.html', {"fname": fname})
In order for fname to show up you'll need to pass that into the render function. You're not doing that in def hello
You need to correctly return the argument into the render function like this:
def hello(request):
...
context = {'fname': fname}
return render(request, 'pops/index.html', context)
Related
I am new to Flask. I started from some Youtube videos,but somehow mine is not working with the extends part. I am getting the output as if I haven't extended the second HTML file specified below. Am I missing something ?
This is my "main.py" file
from flask import Flask,redirect,url_for,render_template
app = Flask(__name__)
#app.route("/")
def index():
return render_template("home.html")
if __name__=="__main__":
app.run(debug=True)
this is "templates/home.html" file
<!doctype html>
<html lang="en">
<head>
<title>mY Page</title>
</head>
<body>
<h1> this is nav----------- bar</h1>
<hr/>
{% include 'templates/test.html' %}
<div id="content">{% block content %}{% endblock %}</div>
</body>
</html>
and this is 2nd html "templates/test.html"
{% extends 'templates/home.html' %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
{% endblock %}
Probably the templates/ part is not required for extends.
Just use:
{% extends 'home.html' %}
in place of:
{% extends 'templates/home.html' %}
and it should work.
I'm newly learning django. I'm trying to learn django by making todo app. I've created a view having template in which I'm showing a list of items to the user using for loop. I've also created a link for each item.Now I want to access the item that user clicked and I should display all details related to that item, for that I've created another view.But the problem is I'm not getting how to access that. Here's my code.
views.py
def display_user_tasks(request):
name = request.user
task_list = Task.objects.filter(user=User.objects.get(username=request.user.username))
context = {
'name': name,
'task_list': task_list,
}
return render(request, 'todo/task_list.html', context)
def about_tasks(request):
name = request.user
task = request.task
context = {
'task': task,
'name': name,
}
return render(request, 'todo/about_tasks.html', context)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Task List</title>
</head>
<body>
<div>
{% if task_list %}
<p> Hello {{ name }} Here are your tasks</p>
{% for task in task_list %}
{{ forloop.counter }}
{{ task }} <br>
{% endfor %}
{% else %}
<p> No tasks yet </p>
{% endif %}
<br>
<button onclick="window.location.href='task-form'">Add task</button>
</div>
</body>
</html>
I've just tried to display whether the task which user clicked is displaying or not.
about_task.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>About tasks</title>
</head>
<body>
{{ name }}<br>
{{ task }}
<p> You will see about your tasks here</p>
</body>
</html>
Finally, I got the answer for my problem. I can send the clicked item as parameter in urls. So, I did it and this parameter takes the value when I use the name the respective url.
I'm learning Flask and this is the file structure of my first project:
This is my app.py:
from flask import Flask, request, render_template
from data import Articles
app = Flask(__name__)
Articles = Articles()
#app.route('/')
def index():
return render_template('home.html')
#app.route('/about')
def about():
return render_template('about.html')
#app.route('/contact')
def contact():
return render_template('contact.html')
#app.route('/articles')
def articles():
return render_template('articles.html', articles = Articles)
#app.route('/article/<string:id>/')
def article(id):
return render_template('article.html', id=id)
if __name__ == '__main__':
app.run(debug=True)
This is my layout.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
{% block head %}
<meta charset="utf-8">
<title>Learning Flask - App</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
{% endblock head %}
</head>
<body>
{% include 'components/_navbar.html' %}
<div class='container'>
{% block content %}
{% endblock %}
</div>
</body>
</html>
This is my home.html which is the only page working properly:
{% extends 'layout.html' %}
{% block content %}
<div class="jumbotron">
<div class="container">
<h1 class="display-3">Hello, world!</h1>
<p>This is a template for a simple marketing or informational website. It includes a large callout called a jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a class="btn btn-primary btn-lg" href="#" role="button">Learn more ยป</a></p>
</div>
</div>
{% endblock %}
This is my contact.html which doesn't show anything after the navigation bar, same problem with rest of the templates:
{% extends 'layout.html' %}
{% block content %}
<h1>WHY THE HELL DOESNT THIS SHOW UP!!</h1>
{% endblock %}
Well, changing the navbar HTML fixed the problem. Don't know what exactly caused the issue but it was probably a matter of conflicting CSS.
I want to render context_dic and the current time to my html file(inherit form another html) But it doesn't work. Could anybody help me fix this problem? Thanks a lot!
This is my python file
def homepage(request):
now=datetime.datetime.now()
list_list = List.objects.order_by('author')
context_dict = {'Lists': list_list}
return render(request, ('index.html',context_dict), {'current_date':now})
And here is my base.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>This is my base page.</title>
</head>
<body>
<p>Hello.</p>
{% block content %}{% endblock %}
</body>
{% block footer%}
<p>It is now {{current_date}}.</p>
{% endblock %}
</html>
And index.html
{% extends "about.html"%}
{% block content %}
{% if lists %}
<ul>
{% for list in lists %}
<li>{{list.title }}
</li>
{% endfor %}
</ul>
{% else %}
<strong>There are no lists present.</strong>
{% endif %}
{% endblock %}
My url is like this
url(r'^home',homepage),
In your render, the context is the argument you set to {'current_date':now}
so if you want both these values in your context you need to add them to the same dict. Do something like:
context_dict = {'Lists': list_list, 'current_date':now}
return render(request, 'index.html', context_dict)
I am using template inheritance in my django project. I used form in my base html page and submit button, When i inherit base template to another template form get disappeared but submit button is still there. I have below templates.
base.html
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
</script>
</head>
<body>
{% block option %}
<div class="row">
<div class="col-lg-3">
<form method = "post" action="">
{% csrf_token %}
{{form}}
<input type="submit" value="Submit" />
</form>
</div>
</div>
{% endblock %}
<div class="row">
{% block content %}{% endblock %}
</div>
</body>
chart.html
{% extends 'base.html' %}
{% block content %}
<head>
{% load static from staticfiles %}
<link rel="stylesheet" href="{% static "bootstrap.css" %}">
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", "1", {packages:["corechart"]});
</script>
</head>
<div id="container" align="center">
{{ column_chart.as_html }}
{% endblock %}
How can i make form visible there in chart html??
EDIT: Added Views
views.py
def select_chart_form(request):
form = SelectChart(request.POST)
if form.is_valid():
if (str(form.cleaned_data['status']) == '1'):
#print "Hello Naresh reverse('chart1')"
return HttpResponseRedirect('/chart1/')
if (str(form.cleaned_data['status']) == '2'):
return HttpResponseRedirect('/chart2/')
context = {
'form' : form
}
return render(request, 'base.html', context)
def video_by_user(request):
analysis = VideoData.objects.annotate(watches_count = Count('user')).order_by('-watches_count')[:10]
data_source = ModelDataSource(analysis,fields=['video_name', 'watches_count'])
column_chart = gchart.ColumnChart(data_source,options={'title': "Top 10 Videos watched by No. Of Users"})
context = {
"data_source": data_source,
"column_chart": column_chart,
}
return render_to_response('chart.html', context)
I am calling video_by_user method..after click on submit button.
The select_chart_form and video_by_user views are completely separate. The first one renders just base.html, and supplies the form variable when it does so. The second one renders chart.html, which inherits from base.html, but it only supplies the variables needed for chart.html itself: it doesn't provide the form needed for base.html. You will need to supply that in video_by_user.