Am i missing something on templates on django - python

This is my code on html file on a django project. I am using this code on this function
def home(request):
context = {
'post': posts
}
return render(request,'blog/home.html',context
It does not display anything when I see page source it's just bacis html code head and body empty
<html>
<head>
<title> </title>
</head>
<body>
{% for post in posts %}
<h1>{{post.title}}</h1>
<p>By {{post.author}} on {{post.date_posted}}</p>
<p>{{post.content}}</p>
{% endfor %}
</body>
</html>```

It is a typo. You need to change the context in your view from:
context = { 'post': posts }
to
context = { 'posts': posts }
^^^^^^^

Related

Implementing Search Form with Django

Hello Stackoverflow community,
I am having trouble with my form not rendering in Django.
Here's my attempt to render an empty form in views.py.
class SearchSite(forms.Form):
query = forms.CharField(label="New Item",
help_text="Search for any article located on the site.")
def search(request):
form = SearchSite()
context = {
"form": form,
"query_matches": query_matches
}
response = render(request, "encyclopedia/layout.html", context)
return response
Here's what my urls.py file looks like:
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:page_title>", views.page, name="wiki"),
path("wiki/", views.search, name="site_search")
]
My layout.html file:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="{% static 'encyclopedia/styles.css' %}" rel="stylesheet">
</head>
<body>
<div class="row">
<div class="sidebar col-lg-2 col-md-3">
<h2>Wiki</h2>
<form action="{% url 'site_search' %}" method="get">
{% csrf_token %}
There should be something here
{{ form }}
<input type="submit">
</form>
<div>
Home
</div>
<div>
Create New Page
</div>
<div>
Random Page
</div>
{% block nav %}
{% endblock %}
</div>
<div class="main col-lg-10 col-md-9">
{% block body %}
{% endblock %}
</div>
</div>
</body>
</html>
I have noticed two particular problems in above screenshot. Firstly, my form does not render when inside my index.html webpage, which extends layout.html. Secondly, when I click the submit button, I get routed to a webpage that has my CSRF token in the url ... and then finally renders my form.
How can I fix this? Thanks everyone.
I have noticed two particular problems in above screenshot. Firstly,
my form does not render when inside my index.html webpage, which
extends layout.html.
Yes. You aren't passing form to index.html. Pass that in the view which renders the homepage. Even if it extends from layout.html, you need to pass it in the context for it to work.
def index(request):
# Your code.
return render(request, 'index.html', {'form': SearchSite()})
Secondly, when I click the submit button, I get routed to a webpage
that has my CSRF token in the url ... and then finally renders my
form.
That's because, in index.html, there is a blank form with a csrf_token, with an action set to /wiki, which calls search when the submit button is pressed. And search gives you layout.html, with the form, and as the form method is GET, it shows it in the url. I suggest changing it to POST if there is confidential data (and even otherwise. Why is there a csrf_token if it is not a POST request? Not needed. If you really want a GET request, then remove the csrf_token).
Here's my solution to the problem I had earlier for any future people visiting the post.
I wrote a form called SearchSite and defined a view called search in my views.py.
class SearchSite(forms.Form):
query = forms.CharField(
help_text="Search for any article located on the site.")
def search(request):
form = SearchSite()
is_substring_of_queries = []
if request.method == "GET":
form = SearchSite(request.GET)
if form.is_valid():
for entry in util.list_entries():
existsIdenticalResult = form.cleaned_data["query"].casefold() == entry.casefold()
existsResult = form.cleaned_data["query"].casefold() in entry.casefold()
if existsIdenticalResult:
return HttpResponseRedirect(reverse("wiki",
kwargs={"page_title": entry}))
elif existsResult:
is_substring_of_queries.append(entry)
context = {
"form": SearchSite(),
"is_substring_of_queries": is_substring_of_queries
}
response = render(request, "encyclopedia/search.html", context)
return response
When my view.search is requested, it will send the response of either an empty form (if accessed by index.html or if there are no results with a message saying there are no results) , an empty form and all the queries that are substrings of the markdown entries or route the client to an exact entry if the query matched.
Here's the routing down in my urls.py so far:
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:page_title>", views.page, name="wiki"),
path("search/", views.search, name="site_search")
]
In my layout.html, I have the following form:
<form action="{% url 'site_search' %}" method="get">
{{ form }}
<input type="submit">
</form>
as well as in my search.html the queries that are substrings of the markdown entries:
{% if is_substring_of_queries %}
<h1>Search Results</h1>
{% for query in is_substring_of_queries%}
<li> {{ query }} </li>
{% endfor %}
{% else %}
<h1>No Results! Try again.</h1>
{% endif %}
If there are any mistakes, please let me know.

not showing the title in django framework

I'm new to django framework and i'm using VS code
this is view.py file
posts = [
{
'author': 'CoreyMS',
'title': 'Blog Post 1',
'content': 'First post content',
'date_posted': 'August 27, 2018'
},
{
'author': 'Jane Doe',
'title': 'Blog Post 2',
'content': 'Second post content',
'date_posted': 'August 28, 2018'
}
]
def home(request):
context = {
'posts': posts
}
return render(request, 'blog/home.html', context)
and this my home.html file
<!DOCTYPE html>
<html lang="en">
<head>
{% if title %}
<title>Django Blog - {{ title }}</title>
{% else %}
<title>Django Blog</title>
{% endif %}
</head>
<body>
{% for post in posts %}
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<p>{{ post.authorname }}</p>
<p>{{ post.postdate }}</p>
{% endfor %}
</body>
</html>
the body part works fine but the title doesn't work , i expect to see the title which is blog post one or blog post 2
where is the problem ?
thank you
def home(request):
context = {
'posts': posts,
'title': posts['title']
}
return render(request, 'blog/home.html', context)
But this kind of use is not good in practice. This is your homepage, not a post page. you don't need a specific post's title on the homepage.
I recommend use like that
Create Post model
Create url path for your view function (for post
page)
Create html page for post_page view function
in models.py and don't forget to migrate your model to the databse with python manage.py makemigrations and python manage.py migrate
import django.db import models
class Post(models.Model):
title = models.CharField(max_length=250)
slug = models.SlugField(
max_length=250,
unique_for_date='publish')
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='blog_posts'
)
content = models.TextField()
date_posted = models.DateTimeField(auto_now_add=True)
# What ever you want you can add
def __str__(self):
return self.title
in urls.py looks like
urlpatterns = [
# your paths what ever you have
path('blog/<slug:post_slug>', views.post_page, name='post_page'),
]
in views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
# and other imports
def home(request):
posts = Post.objects.all()
context = {
'posts': posts
}
return render(request, 'blog/home.html', context)
def post_page(request, post_slug):
post = get_object_or_404(Post, slug=post_slug)
# and other operation you want
return render(request, 'blog/post_page.html', { 'post': post } )
then in your post_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ post.title }}</title>
</head>
<body>
<div>
{{ post.content }}
</div>
</body>
</html>
after all I recommend make a base.html then extend your html pages from it
the body part works fine but the title doesn't work
I does - it prints an empty string for the 'title' var because there's no 'title' var in your context, and this is the expected behaviour
i expect to see the title which is blog post one or blog post 2
Why would you expect such a thing ??? If you want your first post's title, use {{ posts.0.title }}. The template engine will NOT try to "guess" anything (hopefully), it just do what you ask for.
where is the problem ?
Well, perhaps passing a value for title in your context might work ?
def home(request):
context = {
'posts': posts,
'title': "This is my beautiful blog"
}
return render(request, 'blog/home.html', context)
Also and FWIW, you can make your template code a bit more DRY:
<title>Django Blog{% if title %}- {{ title }}{% endif %}</title>

Flask: Why is my view not rendering the template I want it to? [duplicate]

This question already has answers here:
Flask-WTF - validate_on_submit() is never executed
(8 answers)
Closed 4 years ago.
Here is the class I created, model of the flask mega tutorial's RegistrationForm
class eyeReaderInput(FlaskForm):
article = StringField('Article')
submit = SubmitField('Enter')
And I've implemented that class in this view:
#app.route('/eyereader', methods=['GET', 'POST'])
def eyereader():
form = eyeReaderInput()
sTuple = ()
if form.validate_on_submit():
string = wikipedia.page(form.article.data)
for chunk in textwrap.wrap(string, 15):
sTuple += (chunk,)
return render_template('eyereader.html', string = sTuple, form = form)
else:
return render_template('eyereader.html', form = form)
with this being my template of eyereader.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if string %}
<p><span>
{% for s in string %}
[{{s}}]<pre class="tab"></pre>
{% endfor %}
</span></p>
{% else %}
<p>Please input an article name</p>
<form action = "" method = "post">
<p>{{ form.article.label}}<br>
{{ form.article() }}</p>
<p>{{ form.submit() }}</p>
</form>
{% endif %}
</body>
</html>
What I'm hoping to do is for the user to initially access the eyereader site using a 'GET' request (which is what happens when I look at my console), and once the user inserts the wikipedia article he wishes to read, it sends a 'POST' request with a new string parameter which will make {% is string %} true and instead show the wikipedia text.
However when I'm testing this, both 'GET' and 'POST' requests end up going to the input page. Does anyone know what I may be able to change to get this to work? Thanks.
Option #1: Use two templates to handle the conditional content, tying each template to a different form action (GET/POST).
#app.route('/eyereader')
def show_template():
return render_template("eyereader.html")
Option #2: Use JavaScript to dynamically populate content as needed.
<script type="text/javascript">
$('#my_object').on('change', function() {
var selected = $( "#my_object condition:true" ).text();
if(selected == "yes")
$(Do_Something_Here)
});
</script>

django render to request dict name

views.py
from django.shortcuts import render_to_response
from models import Post
def getRecentPosts(request):
posts = Post.objects.all()
# sort by chronological order
sorted_posts = posts.order_by('-pub_date')
# display all posts
return render_to_response('posts.html', {'posts': sorted_posts})
posts.html
<html>
<head>
<title>My Django Blog</title>
</head>
<body>
{% for post in posts %}
<h1>{{post.title}}</h1>
<h3>{{post.pub_date}}</h3>
{{ post.text }}
{% endfor %}
</body>
This code works fine & prints the proper data.... However if i change
return render_to_response('posts.html', {'posts': sorted_posts})
to
return render_to_response('posts.html', {'po': sorted_posts})
and
{% for post in posts %} to {% for post in po %}
in posts.html
It fails to generate any data..... So what is the relation between the dictionary name in view and template

Django and Ajax

Im trying to get a basic app working in Django that incorporates AJAX.
The app will take a domain name and will then send it to the server, which will do a dns lookup on it and then send the response back via AJAX to the client.
Views
from django.http import *
from django.shortcuts import render_to_response
from django.template import RequestContext
import sys
import os
import socket
def main(request):
if request.method == 'POST':
dig_input = request.POST['digInput']
digoutput = socket.gethostbyname(dig_input)
return render_to_response('digajax.html', {'response': digoutput}, context_instance=RequestContext(request))
else:
return render_to_response('digajax.html', context_instance=RequestContext(request))
URLs
url(r'^digajax$', 'digajax.views.main'),
Templates
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.js'></script>
<script type="text/javascript">
function send_request(){
$.get(location.href, function(data){
$("#output").html(data.output);
});
}
</head>
<body>
<form method="post" name="diginput form" action="/digajax">
{% csrf_token %}
<input name="digInput" id="digInput" type="text">
<input type="button" onclick="send_request();" value="Request this page with AJAX">lookup</input>
</form>
{% if response %}
<div id="output">
<p>{{ response|linebreaksbr }}</p>
</div>
{% else %}
<p>no</p>
{% endif %}
</body}
</html>
Without AJAX everything is working. Now that I want to use AJAX Im not what what code I should add to each section.
Any help would be really appreciated...............
Django provides an method on the request object your view is passed which will tell you whether the request was made via XmlHttp, request.is_ajax().
If that method returns true, you probably want to return only the fragment of the page you want to update, instead of the whole page.
If that method returns false, you probably want to return the entire page, since the user either has JavaScript turned off, or there was some type of error which caused the view to be requested normally.
So, your view should look like:
def main(request):
if request.method == 'POST':
dig_input = request.POST['digInput']
digoutput = socket.gethostbyname(dig_input)
if request.is_ajax():
return HttpResponse("<p>%s</p>" % digoutput)
else:
return render(request, 'digajax.html', {
'response': digoutput
})
else:
return render(request, 'digajax.html')
Your JavaScript code should be look like:
<script type="text/javascript">
function send_request(){
$.get(location.href, function(data){
$("#output").html(data);
});
}
</script>

Categories