Can't display database data in Django - python

I am working on library website in which I want to display data from database which is Book name and description. But I'm not able to do that. Here is my code
views.py
from django.shortcuts import render
from .models import *
def index(request):
book_list = Book.objects.all()
return render(request,template_name='index.html', context={'book_list':book_list})
index.html
{% extends "base_generic.html" %}
{% block new_books %}
{% for b in book_list %}
<div class="card">
<img class="card-img-top" src=".." alt="Image">
<div class="card-body">
<h5 class="card-title">{{ book_list }} </h5>
<p class="card-text">Hello this is card text</p>
<a class="btn btn-primary">View this book</a>
</div>
</div>
{% endfor %}
{% endblock %}

You should work with b variable instead of book_list inside of for loop.
If your Book model contains title field, your code might look like this:
{% extends "base_generic.html" %}
{% block new_books %}
{% for b in book_list %}
<div class="card">
<img class="card-img-top" src=".." alt="Image">
<div class="card-body">
<h5 class="card-title">{{ b.title }} </h5>
<p class="card-text">Hello this is card text</p>
<a class="btn btn-primary">View this book</a>
</div>
</div>
{% endfor %}
{% endblock %}

Related

How to call in the google books API in django?

The books are being displayed but when i click on the link it does not lead to the google books.co.in webpage where the book is stored, it displays that the page is not found.
my views.py
def books(request):
if request.method == "POST":
form=DashboardForm(request.POST)
text=request.POST['text']
url="https://www.googleapis.com/books/v1/volumes?q="+text
r = requests.get(url)
answer = r.json()
result_list = []
for i in range(10):
result_dict = {
'title':answer['items'][i]['volumeInfo']['title'],
'subtitle':answer['items'][i]['volumeInfo'].get('subtitle'),
'description':answer['items'][i]['volumeInfo'].get('description'),
'count':answer['items'][i]['volumeInfo'].get('pageCount'),
'categories':answer['items'][i]['volumeInfo'].get('categories'),
'rating':answer['items'][i]['volumeInfo'].get('pageRating'),
'thumbnail':answer['items'][i]['volumeInfo'].get('imageLinks').get('thumbnail'),
'preview':answer['items'][i]['volumeInfo'].get('previewLinks')
}
result_list.append(result_dict)
context={
'form' : form,
'results' :result_list
}
return render(request,'dashboard/books.html',context)
else:
form=DashboardForm()
context={'form' : form}
return render(request,'dashboard/books.html',context)
my books.html template
{% extends 'dashboard/base.html' %}
{% load static %}
{% block content %}
<section class='text-center container'>
<h2><b>SEARCH FOR BOOKS </b></h2>
<p>Enter the search query to obtain your desired book</p><b></b>
<form action="" method="post">
{% csrf_token %}
{{form}}
<input class="btn btn-danger" type="submit" value="Submit">
</form><br>
{% for result in results %}
<a href="{{result.preview}}" target="_blank">
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-md-3">
<img class="img-fluid" src="{{result.thumbnail}}" alt="">
</div>
<div class="col-md-9">
<h3 class="p-0 m-0">{{result.title}}</h3>
<b>
<u>
<h5 class="p-0 m-0">{{result.subtitle}}</h5>
</u>
</b>
{% if result.description %}
<h6 class="p-0 m-1">{{result.description}}</h6>
{% endif %}
<b>
{% if result.categories %}
<h6 class="ml-0 mt-3">Category:
{% for category in result.categories %}
{{category}}
{% endfor %}
</h6>
{% endif %}
{% if result.count %}
<h6 class="ml-0 mt-1">Pages: {{result.count}}</h6>
{% endif %}
{% if result.rating %}
<h6 class="ml-0 mt-1">Rating:{{result.rating}}</h6>
{% endif %}
</b>
</div>
</div>
</div>
</div>
</a>
{% endfor %}
<br>
</section>
{% endblock content %}
I have installed and imported requests and want to redirect to google books page when i click on the book.
enter image description here
The issue seems to be with the value of "preview" in the "result_dict" dictionary. It looks like the "previewLinks" key in the JSON response from the Google Books API does not contain a URL that can be directly accessed.
You can try it like this:
result_dict = {
...
'preview': answer['items'][I]['volumeInfo'].get('previewLinks').get('googlePlay'),
...
}

Extending multiple templates in django

I know a similar question might have been asked here a couple of times before, but I am still not able to find a solution to my problem with the answers provided. So I have five templates. index.html(base template), allposts.html, trending.html and religion.html and political.html. All make up different sections of the homepage complete with there own classes in the database. How do I create a template that extends all these templates? I.e merges all their contents, including data into one. I have tried extending trending.html, using index.html as the base, and then extending allposts.html using trending.html as the base, but the problem is I lose all the data associated to the new base template. Is there an easy way to do this?
religion.html
{% extends 'index.html' %}
{% block religion %}
<section class="category-section">
<div class="container" data-aos="fade-up">
<div class="section-header d-flex justify-content-between align-items-center mb-5">
<h2>Religion</h2>
<div>See All Religion</div>
</div>
<div class="row">
{% for religion in religions %}
{% if forloop.counter < 11 %}
<div class="post-entry-1 col-2 mx-1">
<img src="{{religion.image.url}}" alt="" class="post_img">
<div class="post-meta">
<span class="date">{{religion.category}}</span>
<span class="mx-1">&bullet;</span>
<span>{{religion.created_at}}</span>
</div>
<h2 class="mb-2">{{religion.title}}</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
<p class="mb-4 d-block">{{religion.body|truncatewords:20}}</p>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</section>
{% endblock %}
political.html
% extends 'index.html' %}
{% block content %}
<section class="category-section">
<div class="container" data-aos="fade-up">
<div class="section-header d-flex justify-content-between align-items-center mb-5">
<h2>Politics</h2>
<div>See All Politics</div>
</div>
<div class="row">
{% for politic in politics%}
{% if forloop.counter < 11 %}
<div class="post-entry-1 col-2 mx-1">
<img src="{{politic.image.url}}" alt="" class="post_img">
<div class="post-meta">
<span class="date">{{politic.category}}</span>
<span class="mx-1">&bullet;</span>
<span>{{politic.created_at}}</span>
</div>
<h2 class="mb-2">{{politic.title}}</h2>
<span class="author mb-3 d-block">Ole Pundit</span>
<p class="mb-4 d-block">{{politic.body| safe | truncatewords:20}}</p>
</div>
{% endif %}
{% endfor %}
</div>
</div>
</section>
{% endblock %}
trending.html
{% extends 'index.html' %}
{% load static %}
{% block trending %}
<div class="col-lg-3 trendingslide">
<div class="trending">
<h3>Trending</h3>
<ul class="trending-post table">
{% for trendingpost in trendingposts %}
{% if forloop.counter < 6 %}
<li>
<a href="">
<span class="number count"></span>
<h3>{{trendingpost.title}}</h3>
<span class="author">OlePundit</span>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
allposts.html
{% extends 'index.html' %}
{% load static %}
{% block allposts %}
{% for post in posts reversed %}
{% if forloop.counter < 5 %}
<div class="post-entry-1 col-lg-2 box mx-1">
<img src="{{post.image.url}}" class="post_img">
<div>
<div class="post-meta"><span class="date">{{post.category}}</span> <span class="mx-1">&bullet;</span> <span>{{post.created_at}}</span></div>
<h2>{{post.title}}</h2>
</div>
<p class="mb-4 d-block">{{post.body|truncatewords:75}}</p>
<div class="d-flex align-items-center author">
<div class="photo"><img src="{% static 'assets/img/person-1.jpg' %}" alt="" class="img-fluid"></div>
<div class="name">
<h3 class="m-0 p-0">OlePundit</h3>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endblock %}
index.html(base template)
<section id="posts" class="posts">
<div class="container" data-aos="fade-up">
<div class="row g-5">
{% block allposts %}
{% endblock %}
<!-- Trending Section -->
{% block trending %}
{% endblock %}
<!-- End Trending Section -->
</div>
<!-- End .row -->
</div>
</section> <!-- End Post Grid Section -->
<!-- ======= Politics Category Section ======= -->
{% block content %}
{% endblock %}
<!-- End Politics Category Section -->
<!-- ======= Religion Category Section ======= -->
{% block religion %}
{% endblock %}
<!-- End Religion Category Section -->
views.py
def allposts(request):
posts = Post.objects.all()
return render(request, 'allposts.html', {'posts':posts})
def trending(request):
trendingposts = Post.objects.all()
return render(request, 'trending.html',{'trendingposts':trendingposts})
def political(request):
politics = Politics.objects.all()
return render(request, 'Politics/political.html', {'politics':politics})
def religion(request):
religions = Religion.objects.all()
return render(request, 'Religion/religion.html', {'religions':religions})
```

I want to create a website where users will be posting to the site, How would I make each post appear in a separate card?

Am creating a website where user will be posting information in the site, but when I post in the site, all post appear in a single card while I want each post to appear in a separate card, How would I do this?? would I have to use Javascript in the front end or python in the back end to accomplish this, and how?
Am using python 3.6.8, and django 2.1.8, I have written a code but all post appear in single materialize card
views
def homepage(request):
return render(request=request,
template_name="main/home.html",
context={"documents":Documents.objects.all}
models
class Documents(models.Model):
docs_name = models.CharField(max_length=200)
police_station = models.CharField(max_length=200)
docs_details = models.TextField()
docs_pic = models.ImageField()
def __str__(self):
return self.docs_name
Home template
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
<div class="card">
<div class="card-image">
{% for Doc in documents %}
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
Try:
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
{% for Doc in documents %}
<div class="card">
<div class="card-image">
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
You can achieve what you desire by simply adding the looping construct outside the <div class="card"> like this :
{% extends 'main/base.html' %}
{% block content %}
<a class="waves-effect waves-light btn" href="">button</a>
<div class="row">
<div class="col s12 m9" >
{% for Doc in documents %}
<div class="card">
<div class="card-image">
<p>{{Doc.docs_name}}</p>
<p>{{Doc.police_station}}</p>
<p>{{Doc.docs_details}}</p>
<p>{{Doc.docs_pic}}</p>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
This way your card section alone repeats multiple times.
Earlier since the loop was within the card you got all the items within the same card.

missing nested template display

I am trying to display the content in my portfolio.html file but nothing is showing up.
portfolio section in home.html:
<!-- portfolio -->
<section id="portfolio">
<div class="container">
<div class="row">
<div class="title">
Some of our work
</div>
<div class="caption">
Costco sample
</div>
{% block portfolio %} {% endblock %}
</div>
</div>
</section>
portfolio.html:
{% extends "home/home.html" %}
{% block portfolio %}
<div class="col-md-4 col-sm-6 portfolio-item">
<a href="#" class="portfolio-link">
<div class="portfolio-hover">
</div>
<img src="../static/images/roundicons.png">
</a>
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
</div>
<div class="col-md-4 col-sm-6 portfolio-item">
</div>
{% endblock %}
template format:
#####index.html
{% load staticfiles %}
{% block content %}{% endblock %}
#############
#####home.html
{% extends "index/index.html" %}
{% load staticfiles %}
{% block content %}
{% block portfolio %}{% endblock %}
{% endblock %}
#############
#####portfolio.html
{% extends "home/home.html" %}
{% block portfolio %}
CONTENT
{% endblock%}
{% endblock %}
#############
Missing content in the inspector:
Since your view is rendering home.html, then you don't want portfolio.html to extend it. Rather, you want home.html to include portfolio.html. Instead of using {% block portfolio %}, use {% include "portfolio.html" %}
However, if your view was going to render portfolio.html, then it would extend home.html.
You are trying to render content from portfolio.html in home.html...try the opposite.
You normally render the child templates
Read https://docs.djangoproject.com/en/1.7/topics/templates/ ...slowly :P. Bassically you create a basic generic template (parent - home.html in your case) that contains some blocks and then extend it and override the blocks on the children (portfolio.html)

Is this how to check if an object has no related objects in templates?

This is what I currently has to check if the author has some photos in the related photo model:
{% if author.photo_set.count > 0 %}
<h2>...</h2>
<div style="clear: both;"></div>
<div class="author_pic">
{% for photo in author.photo_set.all %}
<img src="..." />
{% endfor %}
<div style="clear: both;"></div>
</div>
<div style="clear: both;"></div>
{% endif %}
Is this the right way or I can avoid having two queries somehow?
Thanks.
You can use the with tag to avoid multiple queries.
{% with author.photo_set.all as photos %}
{% if photos %}
<h2>...</h2>
<div style="clear: both;"></div>
<div class="author_pic">
{% for photo in photos %}
<img src="..." />
{% endfor %}
<div style="clear: both;"></div>
</div>
<div style="clear: both;"></div>
{% endif %}
{% endwith %}
There is also the empty tag that you can use within a for loop, but that probably doesn't apply to your example.
https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#for-empty
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% empty %}
<li>Sorry, no athlete in this list!</li>
{% endfor %}
<ul>
AS #pyrospade suggsted, you can look if the photos object exists. Or you could also check the length (check the length template tag) of the list of photo_set as follows:
{% if author.photo_set.all|length > 0 %}
<h2>...</h2>
<div style="clear: both;"></div>
<div class="author_pic">
{% for photo in author.photo_set.all %}
<img src="..." />
{% endfor %}
<div style="clear: both;"></div>
</div>
<div style="clear: both;"></div>
{% endif %}

Categories

Resources