Django Pagination with get_absolute_url method - python

Are their any special rules with using Django's Paginator with the model method get_absolute_url? I am trying to call this method, but it isn't working??
Here's my template:
<ul class="products thumb-info-list">
{% for product in products.object_list %}
<li class="col-md-3 product">
{% if product.on_sale %}
<a href="{{ product.get_ablsolute_url }}">
<span class="onsale">Sale!</span>
</a>
{% endif %}
<span class="thumb-info">
<a href="{{ product.get_ablsolute_url }}" class="add-to-cart-product">
<span><i class="icon icon-tag"></i>{{ product.title }}</span>
</a>
<a href="{{ product.get_ablsolute_url }}">
<span class="thumb-info-image">
<span class="thumb-info-act">
<span class="thumb-info-act-left"><em>View</em></span>
<span class="thumb-info-act-right"><em><i class="icon icon-plus"></i> Details</em></span>
</span>
<img alt="" class="img-responsive" src="{{ STATIC_URL }}{{ product.image_one }}">
</span>
</a>
<span class="thumb-info-content">
<a href="{{ product.get_ablsolute_url }}">
<h4>{{ product.title }}</h4>
<span class="price">
{% if product.on_sale %}
<del><span class="amount">${{ product.unit_price|floatformat:0 }}</span></del>
{% endif %}
<ins><span class="amount">${{ product.sale_price|floatformat:0 }}</span></ins>
</span>
</a>
</span>
</span>
</li>
{% endfor %}
</ul>

It looks like a typo in your template:
product.get_ablsolute_url
should be:
product.get_absolute_url

Related

Django search bar isn't giving correct results

views.py
from django.shortcuts import render
from ecommerceapp.models import Product
from django.db.models import Q
def searchResult(request):
products=None
query=None
if 'q' in request.GET:
query = request.GET.get('q')
products=Product.objects.all().filter(Q(name__contains=query) | Q(desc__contains=query))
return render(request,'search.html',{'query':query,'products':products})
In views.py I have imported a model named 'Product' of another application.
search.html
{% extends 'base.html' %}
{% load static %}
{% block metadescription %}
Welcome to FASHION STORE-Your Beauty
{% endblock %}
{% block title %}
Search-FASHION STORE
{% endblock %}
{% block content %}
<div>
<p class="text-center my_search_text">You have searched for :<b>"{{query}}"</b></p>
</div>
<div class="container">
<div class="row mx_auto">
{% for product in products %}
<div class="my_bottom_margin col-9 col-sm-12 col-md-6 col-lg-4" >
<div class="card text-center" style="min-width:18rem;">
<img class="card-img-top my_image" src="{{product.image.url}}" alt="{{product.name}}" style="height:400px; width:100%;">
<div class="card_body">
<h4>{{product.name}}</h4>
<p>₹{{product.price}}</p>
</div>
</div>
</div>
{% empty %}
<div class="row mx_auto">
<p class="text-center my_search_text">0 results found.</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
navbar.html
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item dropdown {% if 'ecommerceapp' in request.path %} active {% endif %} ">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Shop
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'ecommerceapp:allProductCategory' %}">All Products</a></li>
{% for cat in links %}
<li><a class="dropdown-item" href="{{cat.get_url}}">{{cat.name}}</a></li>
{% endfor %}
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href=""><i class="fa fa-shopping-cart"></i></a>
</li>
</ul>
<form class="d-flex" action="{% url 'search_app:searchResult' %}" method="get">
{% csrf_token %}
<input class="form-control me-2" type="search" placeholder="Search" name="q" aria-label="Search">
<button class="btn btn-outline-success" type="submit"><i class="fa fa-search"></i></button>
</form>
</div>
</div>
</nav>
When I'm searching using search bar, not getting the correct results. When giving the word completely, correct results are getting.
Example: When I type x in the search bar, it give me the results 'shirt' instead of giving '0 results found'.
Example: When I type x in the search bar, it give me the results 'shirt' instead of giving '0 results found'.
The __contains is used to check whether the field contains given word or not, it is case-sensitive. And using | in Q objects means it is optional and works as OR condition, so maybe it is possible when you type x, the name field doesn't contains x but the field desc contain x that's why you are getting the shirt as instance or else you can simply put the query to Product.objects.filter(Q(name__contains=query)) and .all() only creates the copy of the Queryset so it doesn't require here.

Django with Bootstrap Carousel

My code it's displaying image but not changing the image in the bootstrap carousel when I click the button to pass
{% if variation.extravariationproductpicture_set.all %}
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for picture in variation.extravariationproductpicture_set.all %}
<div class="carousel-item {% if forloop.first %} active {% endif %}">
<img class="d-block w-100" src="{{picture.image.url}}" alt="First slide">
</div>
{% endfor %}
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
{% endif %}

NoReverseMatch at /listings/ Reverse for 'listing' not found. 'listing' is not a valid view function or pattern name

So I'm getting this error when I visit the page, I'm trying to use paginator and I don't know where i'm wrong, index function handles the page I'm talking about
views.py
def index(request):
listings = Listing.objects.all()
paginator = Paginator(listings, 3)
page = request.GET.get('page')
paged_listings = paginator.get_page(page)
params = {'listings':paged_listings}
return render(request, 'listings/listings.html', params)
def listing(request, listing_id):
return render(request, 'listings/listing.html')
def search(request):
return render(request, 'listings/search.html')
listings.html
{% extends 'base.html' %}
{% block content %}
{% load humanize %}
<!-- Breadcrumb -->
<section id="bc" class="mt-3">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{% url 'index' %}">
<i class="fas fa-home"></i> Home</a>
</li>
<li class="breadcrumb-item active"> Browse Listings</li>
</ol>
</nav>
</div>
</section>
<!-- Listings -->
<section id="listings" class="py-4">
<div class="container">
<div class="row">
{% if listings %}
{% for listing in listings %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card listing-preview">
<img class="card-img-top" src="{{ listing.photo_main.url }}" alt="">
<div class="card-img-overlay">
<h2>
<span class="badge badge-secondary text-white">${{ listing.price | intcomma}}</span>
</h2>
</div>
<div class="card-body">
<div class="listing-heading text-center">
<h4 class="text-primary">{{ listing.title }}</h4>
<p>
<i class="fas fa-map-marker text-secondary"></i>{{ listing.city }} {{ listing.state }}, {{ listing.zipcode }}</p>
</div>
<hr>
<div class="row py-2 text-secondary">
<div class="col-6">
<i class="fas fa-th-large"></i>Sqfit: {{ listing.sqft }}</div>
<div class="col-6">
<i class="fas fa-car"></i>Garage: {{ listing.garage }}</div>
</div>
<div class="row py-2 text-secondary">
<div class="col-6">
<i class="fas fa-bed"></i>Bedrooms: {{ listing.bedrooms }}</div>
<div class="col-6">
<i class="fas fa-bath"></i>Bathrooms: {{ listing.bathrooms }}</div>
</div>
<hr>
<div class="row py-2 text-secondary">
<div class="col-12">
<i class="fas fa-user"></i>{{ listing.realtor.name }}</div>
</div>
<div class="row text-secondary pb-2">
<div class="col-6">
<i class="fas fa-clock"></i>{{ listing.list_date | timesince }}</div>
</div>
<hr>
More Info
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="col-md-12">
<p>No Listings Available</p>
</div>
{% endif %}
<!-- Listing 1 -->
</div>
<div class="row">
<div class="col-md-12">
{% if listings.has_other_pages %}
<ul class="pagination">
{% if listings.has_previous %}
<li class="page-item">
«
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">«</a>
</li>
{% endif %}
</ul>
{% endif %}
{% for i in listings.paginator.page_rage %}
{% if listings.number == i %}
<li class="page-item active">
<a class="page-link">{{ i }}</a>
</li>
{% else %}
<li class="page-item">
{{i}}
</li>
{% endif %}
{% endfor %}
</div>
</div>
</div>
</section>
{% endblock %}
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name="listings"),
path('<int:listing_id>', views.listing, name="=listing"),
path('search', views.search, name="=search"),
]
There's a Typo in your urls.py
Try to use this :-
path('listing/<int:listing_id>/', views.listing, name='listing'),
Where was the typo ?
You were using this :-
path('<int:listing_id>', views.listing, name="=listing"),
----------------------------------------------^

Hide Elements within Jinja2 template? Any possible way to hide a button?

I am working on my web application using Python and Flask. I have got a navbar and some buttons on it and I would like to hide one of buttons when I am not on the index page. Is that possible? I would like the button "select brand" to be visible only on index.html page.
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-default fixed-top ">
<div class="container">
<div class="navbar-header">
<button button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" rel="home" href="{{ url_for('main.index') }}" title="Mobile phones and accessories">
<img style="max-width:40px; margin-top: -9px;"
src="http://www.logospng.com/images/38/devfest-2016-38885.png" >
</a>
</div>
<div id="navbar" class="collapse navbar-collapse navbar-responsive-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
{% if current_user.is_authenticated and current_user.admin %}
<li>Add phone</li>
<li>Add brand</li>
{% endif %}
<li class="dropdown">
Select brand <span class="caret"></span>
<ul class="dropdown-menu">
{% for brand in brands %}
<li class="list-group-item">
{{ brand }}
{% endfor %}
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="glyphicon glyphicon-user"> </span> {{ current_user.username }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('auth.logout') }}" >Logout</a></li>
</ul>
</li>
{% else %}
<li><a class="nav-link" href="{{ url_for('auth.login') }}" >Login</a></li>
<li><a class="nav-link" href="{{ url_for('auth.register') }}" >Register</a></li>
{% endif %}
</ul>
<form class="navbar-form navbar-right" method='POST' action="{{ url_for('phones.search') }}">
<div class="form-group">
<input class="search-query form-control" placeholder="Search..." aria-label="Search" type="text" name="search">
</div>
</form>
</div>
</div>
</nav>
{% endblock %}
Create a new variable within your index route and pass that variable into the render_template method of said route. The presence of this variable will determine if the <button> or link within your <nav> should be rendered or not. Since the <nav> will be shared across all other layouts, its HTML code should be put within your base layout, or the layout which all other views are inheriting from.
Something along the lines of:
index route:
#app.route("/")
def index():
# isIndex is the variable we will use to determine
# whether or not to render your navigation link or button
return render_template('index.html', isIndex=True)
base layout file:
<div class="navbar-nav">
{% if isIndex %}
<a class="nav-item nav-link" href="">linkOnlyForIndexPage</a>
{% else %}
<a class="nav-item nav-link" href="">link1</a>
<a class="nav-item nav-link" href="">link2</a>
{% endif %}
</div>
This is exactly what you're already doing with {% if current_user.is_authenticated %} for your navigation links. The reason this works is because the index route is the only route which sets this variable, within your jinja2 templates, so all other routes which render corresponding views will default to false on this conditional check: {% if isIndex %}
Hopefully that helps!
I think this will work.
Set the following on your child pages:
{% set active_page = "index" %}
Then in your base template:
{% if active_page == "index" %}
... button html here
{% endif %}

how to use for loop with bootstrap carousel

I have figured out how to use bootstrap carousel but problem is I want to render my featured stories to be in the carousel.
currently I have a carousel that shows three slides, but what I'm trying to do is to have featured stories instead of the three slides.
<div class='carousel slide' id="myCarousel">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#myCarousel"></li>
<li class="active" data-slide-to="1" data-target="#myCarousel"></li>
<li class="active" data-slide-to="2" data-target="#myCarousel"></li>
</ol>
<div class="carousel-inner">
<div class="item active" id="slide1">
<img src="http://i.imgur.com/SQ691ZO.jpg" >
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
<div class="item" id="slide2">
<img src="http://i.imgur.com/zN4h51m.jpg" >
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
<div class="item" id="slide3">
<img src="http://i.imgur.com/3ruWvoG.jpg">
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
</div>
<a class="left carousel-control" data-slide="prev" href="#myCarousel"><span class="icon-prev"></span></a>
<a class="right carousel-control" data-slide="next" href="#myCarousel"><span class="icon-next"></span></a>
So this is what I tried that's not quite working.
I have
{% for a in featuredStory %}
{{a.title}}
{{a.sub}}
<img src='{{a.get_featuredImage_url}}' class="img-rounded" alt="Cinque Terre" width="330" height="236"/>
{% endfor %}
working fine, but problem is to incorporate these with carousel.
with one featured story it works but with more than one, I get one in the top one in the bottom.
Here;s what I tried
<div class="row">
<div class="col-sm-8">
{% for a in featuredStory %}
<div class='carousel slide' id="myCarousel">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#myCarousel"></li>
<li class="active" data-slide-to="1" data-target="#myCarousel"></li>
<li class="active" data-slide-to="2" data-target="#myCarousel"></li>
</ol>
<div class="carousel-inner">
<div class="item active" id="slide1">
<img src='{{a.get_featuredImage_url}}' class="img-rounded" alt="Cinque Terre" width="330" height="236"/> <div class="carousel-caption">
<h4> {{a.title}}</h4>
<p> {{a.sub}}
</p>
</div>
</div>
</div>
<a class="left carousel-control" data-slide="prev" href="#myCarousel"><span class="icon-prev"></span></a>
<a class="right carousel-control" data-slide="next" href="#myCarousel"><span class="icon-next"></span></a>
{% endfor %}
</div>
</div>
You can use the for loop inside carousel-inner:
<div class="carousel-inner">
{% for a in featuredStory %}
<div class="item {% if forloop.counter == 1 %}active{% endif %}" id="slide{{ forloop.counter }}">
<img src="{{ a.get_featuredImage_url }}" >
<div class="carousel-caption">
<h4>{{ a.title }}</h4>
<p>{{ a.sub}}</p>
</div>
</div>
{% endfor %}
</div>
Make sure to activate the first item by checking the counter:
{% if forloop.counter == 1 %}active{% endif %}
If there are other information such as class, title etc. that also you can set in context on the featuredStory and then render it here same as title or url.
Create div[class=item] dynamically with for loop in next way:
{% for item in featuredStory %}
<div class="item" id="slide{{forloop.counter}}">
<img src="item.get_featuredImage_url">
<div class="carousel-caption">
<h4>{{ item.title }}</h4>
<p>{{ item.sub }}</p>
</div>
</div>
{% endfor %}
I used loop.index instead of forloop.counter
<div class="carousel-inner">
{% for item in sliders %}
<div class="carousel-item {% if loop.index == 1 %}active{% endif %}" id="slide{{ loop.index }}" >
<img class="d-block w-100" width="330" height="236" src="{{ url_for('static', filename='images/sliders/') }}{{ item.imagelocation }}" alt="{{item.filmtitle}}">
<div class="carousel-caption">
<h4>{{ item.filmtitle }}</h4>
</div>
</div>
{% endfor %}
</div>

Categories

Resources