A Car Sale point
Project features
- User login by Email/Facebook/Google
- User registration
- User password reset by email
- PostgreSQL database of cars
- Admin panel login and dashboard
- Search functionality
- User's Car Inquiry
- Email notifications of new inquiry to admin panel and via email
Previous considerations:
- Python 3.11 installed
- Pip installed (comes with Python 3, no worries)
- Virtualenv installed (comes with Python 3, no worries)
- Python added to your local variables
If you have python 3.11 or other versions, it's necessary to configure a new environment because the default environment with which this project runs works under Python 3.9.
To configure a new environment with your Python version, do this:- Delete the
env
folder on the root of this project - Create a new env:
python -m venv env
Note: It's known that the package psycopg2-binary==2.9.5 is compatible with python 3.11 version and psycopg2-binary==2.9.3 (used in this project) is compatible with python 3.9 If you have python 3.11, be careful to make this change in the requirements.txt (meaning change to psycopg2-binary==2.9.5 as we use Python 3.9 that works with psycopg2 2.9.3)
- Delete the
Start here:
- Clone the repository to your local folder
- Open the folder repo with VS code or git bash
- In VS terminal or git bash, input the following commands
env/Scripts/activate #for vscode # for git bash: source env/Scripts/activate pip install -r requirements.txt # don't forget to change here to psycopg2-binary==2.9.5 if you use python 3.11
- Set
carsale/settings.py
environment parameters with thecarsale/.env
file to configure your database with PostgreSQLDEBUG=True SECRET_KEY='anything' DB_USER=your_postgresql_user DB_PASSWORD=your_postgresql_user_password DB_NAME=your_datbase_name EMAIL_HOST_USER=your_gmail EMAIL_HOST_PASSWORD=your_gmail_generated_password
- Create your database in PgAdmin
- Once installed PostgreSQL, create
your_postgresql_user
andyour_postgresql_user_password
- Create an empty database and name it as
your_datbase_name
- To load the default database use the file
database.sql
given in the root of this project - In order to load the database aforementioned, go to your PostgreSQL database and right click on it, and choose the restore option, then pick the
database.sql
file, and voilá you will have the default admin and users to login (the usernames are admin and user, and password is password :D)
- Once installed PostgreSQL, create
- Continue the setup in the terminal, we are about to set this whole thing up
python manage.py collectstatic python manage.py makemigrations python manage.py migrate python manage.py runserver 8000 #or any free port you got
- Navigate to the home page
http://192.168.0.127:8000/
and login with the superuser you created, add leads and agents as you want inhttp://192.168.0.127:8000/admin
or create your agent acc in the home page.
Name: car-sale-site, open it with git bash or or VSCode
virtualenv --version
python -m venv env
source env/Scripts/activate
pip freeze
pip install django==3.0.7
python -m pip install --upgrade pip
django-admin.py startproject carsale .
#django-admin startproject carsale .
#deactivate
python manage.py runserver 8000 #or any free port
Stop the server a while (ctrl + c
)
In the GUI bash:
python manage.py startapp pages
Pages app is created
Go to carsale/settings.py and add the app just created with
INSTALLED_APP=[
'pages.apps.PagesConfig', #name: .PagesConfig is the same in class: pages/apps.py
In carsale/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('pages.urls')),
]
Comment out admin line in pages/urls.py:
#from django.contrib import admin
from django.urls import path
from . import views
urlpatterns=[
#path('admin/', admin.site.urls),
path('',view,home, name='home'), #ERROR HERE views.home
]
Import the render and create your views here.
from django.shortcuts import render
def home(request):
return render(request,'pages/home.html')
- Create a new foler named templates in the root
- Create new folder inside templates called pages
- create new file inside templates/pages: home.html
- Add:
<h2>Hello World</h2>
-In carsale/settings.py add in the zone of TEMPLATES, line 58
'DIRS':['templates'],
source env/Scripts/activate
python manage.py runserver 8000
Replace content of home by the template and SAVE IT:
index.html -> templates/pages/home.html
- Create carsale/static
- Copy Folders (css,fonts and js imag) from Template to carsale/static
STATIC_ROOT = os.path.join(BASE_DIR, 'static') # from databases variable name location
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'carsale/static'),
]
- With the server paused, add the command TO PUSH STATIC into a folder in the project where all the files are uploaded:
python manage.py collectstatic
- In templates/pages/home.html
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
-
Start the server again and do the following changes
href="css/bootstrap.min.css"
->href="{% static 'css/bootstrap.min.css' %}"
for Lines 11-24, 27, 28, 38, 125, 134, 143, 1236-1254 -
In carsale/static/js/app.js, search for logo (ctrl +f) change there (lines: 111,117,119,123) to
'static/img/logos/black-logo.png'
- Create file: templates/base.html
- Cut lines of home.html from the beginning to line 118 and pase it to base.html. After, add it to base.
{% block content %}
{% endblock %}
-
Cut lines of home.html to base.html, lines from
<script src="{% static 'js/jquery-2.2.0.min.js' %}" .. </body>
and past it to base.html -
Add those lines also in in head of templates/home.html
{% extends 'base.html' %}
{% block content %}
{% load static %}
ALL CODE HERE
{% endblock %}
-
Create folder templates/includes
-
Create file templates/includes/navbar.html
-
Create file tempaltes/includes/topbar.html
-
Create file tempaltes/includes/footer.html
-
Cut lines of base.html
<!-- Top header start -->
: => topbar.html
:
<!-- Top header end -->
- Cut lines of base.html
<!-- Main header start -->
: => navbar.html
:
<!-- Main header end -->
- Cut lines of home.html
<!-- footer start -->
: => footer.html
:
<!-- footer end -->
- In base.html, add the following lines before:
{% block content %} {% endblock %}
and after it
{% include 'includes/topbar.html' %}
{% include 'includes/navbar.html' %}
{% block content %}
{% endblock %}
{% include 'pages/footer.html' %}
- Add in path in pages/urls.py
path('about', views.about, name='about'),
- Add in /pages/view.py
def about(request):
return render(request,'pages/about.html')
def services(request):
return render(request,'pages/services.html')
def contactrequest):
return render(request,'pages/contact.html')
-
Add to file templates/pages/about.html, /services.html and /contact.html
- In about.html:
<h2>About</h2>
- In services.html:
<h2>Services</h2>
- In contact.html:
<h2>Contact</h2>
- In about.html:
-
Test: localhost/about
- Enable button: about, services, and contact
- Change this line in templates/includes/navbar.html
href="/carhouse/about.html" -> href="{% url 'about' %}" href="{% url 'services' %}" href="{% url 'contact' %}"
- Pages Template Implementation 3.5
- Insert from carhouse folder/about.html to templates/pages/about.html
{% extends 'base.html' %} // add this line
{% block content %} // add this line
<!-- Sub banner start -->
<!-- Sub Banner end -->
{% endblock %} // add this line
- Make available button of home inside about.html, go back to home
<li><a href="{% url 'home' %}">Home</a></li> //line modified
- Add more in templates/pages/about.html from folder/about.html
<!-- Service center strat --> // line 139
<!-- Our team end --> // line 298
- Update Static images in /templates/pages/about.html
{% load static %} \\add in line 4 after block content
{% static 'img/car/car-1.jpg' %} //29, 42
{% static 'img/car/car-1.jpg' %} //32, 47
{% static 'img/car/car-1.jpg' %} //35, 52
- Insert from carhouse folder/services.html to templates/pages/services.html
{% extends 'base.html' %}
{% block content %}
<!-- Sub banner start -->
:
: <li><a href="{% url 'home' %}">Home</a></li>
:
<!-- Sub Banner end -->
<!-- Services start -->
:
:
<!-- Services end -->
{% endblock %}
- Insert from carhouse folder/contact.html to templates/pages/contact.html
{% extends 'base.html' %}
{% block content %}
<!-- Sub banner start -->
:
: <li><a href="{% url 'home' %}">Home</a></li>
:
<!-- Sub Banner end -->
<!-- Contact 2 start -->
:
:
<!-- Contact 2 end -->
{% endblock %}
- Make available search option in templates/pages/about.html
Copy
<!-- Full Page Search -->
CODE of home.html in templates/base.html
{% block content %}
{% endblock %} // AFTER THESE LINES
<!-- Full Page Search -->
:
</div>
-
Install PostgresSQL: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
-
Modify the default browser: In the Windowd system tray, rick click in Postgres icon and configure:
- "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --app=%URL% -> for chrome
- "C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe" --app=%URL% -> for brave
-
Create Database:
- Rick click in Databases > Create > Database
- Database: your_database_name
- Owner: your_owner
- Save it
-
In carsale/setting.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'your_database_name',#os.path.join(BASE_DIR, 'db.sqlite3'), edited
'USER': 'your_owner', # edited
'PASSWORD': 'your_password', # edited
'HOST': 'localhost', # edited
}
}
- In your project environment, install the package: psycopg2
pip install psycopg2
python manage.py makemigrations
python manage.py migrate
winpty python manage.py createsuperuser
user: your_super_user
email: your_email
pass: your_password
- Run the server: python manage.py runserver 8000
- Go to: localhost:8000/admin with the credentials just created for the super user
- In pages/models.py
from django.db import models
class Team(models.Model):
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
designation = models.CharField(max_length=255)
photo = models.ImageField(upload_to='photos/%Y/%m/%d')
facebook_link = models.URLField(max_length=100)
twitter_link = models.URLField(max_length=100)
google_plus_link = models.URLField(max_length=100)
created_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.first_name #to make the name of user display in DB
- Stop server and install the pillow package
pip install pillow
python manage.py makemigrations # create pages/migrations/0001_initial.py
python manage.py migrate # create database structure
python manage.py runserver 8000
Whenever a change is done in pages/models.py (DB), migrations commands is needed
- In pages/admin.py add and reload page localhost:8000/admin
from .models import Team
# Register your models here.
admin.site.register(Team)
A Teams(Plural of Team DB created) tag has been created in PAGES under
localhost:8000/admin
- In localhost:8000/admin
- Add a user: Click in Teams > Add Team (button on the left corner, complete data and upload pic)
Add at the end /carsale/settings.py
# MEDIA settings
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
- Add in carsale/urls.py
from django.conf.urls.static import static # added
from djanfo.conf import settings # added
path('',include('pages.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # added
- Add the teams in
http://localhost:8000/admin/pages/team/
- Fill their names, last names, upload photo and social media link in pages/views.py, add the following:
from .models import Team #Added this line on top
def home(request):
teams = Team.objects.all()
data = {
'teams' : teams,
}
return render(request,'pages/home.html', data)
def about(request):
teams = Team.objects.all()
data = {
'teams' : teams,
}
return render(request,'pages/about.html', data)
-
Make pic and info of teams avaialable in home.html and about.html
-
In templates/pages/home.html
- Line: 891
<!-- Our team start -->
- Delete the 4 views from 919 to 990, just one
<div class="slick-slide-item">
may remain of the 5 - Encapsulate the remaining view with a for loop
{% for team in teams %} <div class="slick-slide-item"> : <h4><a href="...">Brandon Miller</a></h4> => ">{{team.first_name}} {{team.last_name}}</a></h4> <h5>{{team.designation}}</h5> : </div> {% endfor %}
- Line 906:
img src="img/avatar/avatar-12.jpg" => img src="team.photo.url"
- Line 909 - 911
a href="#" class="facebook-bg"><i class="fa => 909 CHANGED TO AND SO ON: a href="{{team.facebook_link}}" target="_blank" class="facebook-bg"><i class="fa.. a href="{{team.twitter_link}}" target="_blank" class="facebook-bg"><i class="tw.. a href="{{team.google_plus_link}}" target="_blank" class="facebook-bg"><i class="go..
- Line: 891
-
In templates/pages/about.html
- Line: 73
- Delete the 4 views from 102 to 173, just one
<div class="slick-slide-item">
may remain of the 5 - Encapsulate the remaining view with a for loop
{% for team in teams %} <div class="slick-slide-item"> : <img src="img/avatar/avatar-12.jpg" => <img src="{{team.photo.url}}" <h5>{{team.designation}}</h5> : </div> {% endfor %}
- Line 98:
..detail.html">Brandon Miller
=>..detail.html">{{team.first_name}} {{team.last_name}} <h5>{{team.designation}}</h5>
- Line 92 - 94:
a href="#" class="facebook-bg"><i class="fa => 909 CHANGED TO AND SO ON: a href="{{team.facebook_link}}" target="_blank" class="facebook-bg"><i class="fa.. a href="{{team.twitter_link}}" target="_blank" class="facebook-bg"><i class="tw.. a href="{{team.google_plus_link}}" target="_blank" class="facebook-bg"><i class="go..
-
Fixing home button of navbar and logo
- In templates/indlues/navbar.html,
- Line 25, modified by =>
<a class="nav-link dropdown-toggle" href="{% url 'home' %}">
- Line 6, modified by
<a class="navbar-brand company-logo" href="{% url 'home' %}">
In pages/admin.py modify
from django.contrib import admin
from .models import Team
from django.utils.html import format_html
# Register your models here.
class TeamAdmin(admin.ModelAdmin):
def thumbnail(self, object):
return format_html('<img src="{}" width="40" style="border-radius: 50px;" />'.format(object.photo.url)) # to add photo
thumbnail.short_description = 'Photo'
list_display = ('id', 'thumbnail', 'first_name', 'designation', 'created_date')
list_display_links = ('id','thumbnail','first_name',) # to make it clickable
search_fields = ('first_name','last_name','designation')
list_filter = ('designation')
admin.site.register(Team, TeamAdmin)
- Templates/includes/topbar
..fa-phone"></i>+51-997-008-163</a>
..ssel.com"><i class="fa fa-envelope"></i>[email protected]</a>
..ssel.com"><i class="fa fa-clock-o"></i>Mon - Sat: 8:00am - 4:00pm</a>
-
Replace
<p class="copy">© 2023 <a href="#">carsale Corp.</a> All Rights Reserved.</p>
with<p class="copy">© {% now 'Y' %} carsale Corp. All Rights Reserved.</p>
-
Also in line 14:
<li><a href="#" class="facebook-bg"... => <li><a href="https://linkedin.com/" target="_blank" class..
<li><a href="#" class="twitter-bg"... => <li><a href="https://linkedin.com/" target="_blank" class..
<li><a href="#" class="google-bg"... => <li><a href="https://linkedin.com/" target="_blank" class..
<li><a href="#" class="linkdein-bg"... => <li><a href="https://linkedin.com/" target="_blank" class..
- And in Templates/pages/home.html, line 938, questions
<a href="contact.html" class= ... => <a href="{% url 'contact' %}" class=..
- This
<a class="nav-link dropdown-toggle" href="{% url 'home' %}">
Home
</a>
- Modified to
<a
{% if '/' == request.path %}
class="nav-link active"
{% else %}
class="nav-link"
{% endif %}
href="{% url 'home' %}">
Home
</a>
- And
<a class="nav-link" href="{% url 'about' %}">
About
</a>
- To
<a
{% if 'about' in request.path %}
class="nav-link active"
{% else %}
class="nav-link"
{% endif %}
href="{% url 'about' %}">
About
</a>
- Also
<a class="nav-link" href="{% url 'services' %}">
Services
</a>
- Changed to
<a
{% if 'services' in request.path%}
class="nav-link active"
{% else %}
class="nav-link"
{% endif %}
href="{% url 'services' %}">
Services
</a>
- Here same in
<a class="nav-link" href="{% url 'contact' %}">Contact</a>
</li>
<li>
<li class="nav-item dropdown m-hide">
<a href="#full-page-search" class="nav-link h-icon">
- Modified to
<a
{% if 'contact' in request.path %}
class="nav-link active"
{% else %}
class= "nav-link"
{% endif %}
href="{% url 'contact' %}">
Contact
</a>
- In templates/pages/home.html, line 16
<a href="services.html" class... => <a href="{% url 'services' %}" class...
- Stop the server, and create a new app
python manage.py startapp cars
- In carsale/setting.py add in Installed_apps, line 33
INSTALLED_APPS = [
'cars.apps.CarsConfig',
- Copy file pages/urls.py to cars and edit cars/urls.py. Also delete all inside urlpatterns and add
urlpatters = [
path('', views.cars, name='cars'),
]
- In carsale/urls.py, inside urlspatterns brackets
urlpatterns = [
...
path('cars/',include('cars.urls')),
...
]+ static.... ROOT)
- In cars/views.py, add
def cars(request):
return render(request, 'cars/cars.html')
- In templates, create the folder cars (templates/cars) and the file cars.html (templates/cars/cars.html)
<h2>Cars</h2>
- Now localhost:8000/cars is available but not the buttom Cars. To make cars buttom clickable, add in Templates/include/navbar.html, line 26,
href="{% url 'cars' %}"
- Add in templates/cars/cars.html,
{% extends 'base.html' %}
{% block content %}
<!-- Sub banner start, line 124-->
...
<!-- Sub Banner end, line 136-->
<!-- Featured car start, line 138-->
...
<!-- Featured car end, line 691-->
{% endblock %}
- Activate home button inside localhost/cars.html, line 10:
<li><a href="index.html">Home</a></li> => <li><a href="{% url 'home' %}">Home</a></li>
- Make cars button clickable in HOME, templates/includes/navbar.html, line 25
<li class="nav-item">
<a <!-- from cars/urls.py -->
{% if 'cars' in request.path %}
class="nav-link active"
{% else %}
class="nav-link"
{% endif %}
href="{% url 'cars' %}">
Cars
</a>
</li>
Note: Sometimes identation is a problem. To solve those kind of problems, delete the identation and add spaces manually, notepad prodives default tabs, while Atom edutir receives text in form of SPACES
- Fix image logo in cars.html. In carsale/static/js/app.js, line 111, 117, 119
..attr('src', 'static/img... => attr('src', '../static/img..
- Reload page and clean cache with CTRL + F5
- In cars/admin.py, add
from .models. import Car
admin.site.register(Car)
- In cars/models.py , add from FILE: 6.1 choices_list_car_model.txt
from django.db import models
from datetime import datetime
class Car(models.Model):
state_choice = (
('AL', 'Alabama'),
('AK', 'Alaska'),
('AZ', 'Arizona'),
...
('WY', 'Wyoming'),
)
car_title = models.CharField(max_length=255)
year_choice = []
for r in range(2000, (datetime.now().year+1)):
year_choice.append((r,r))
features_choices = ( # from choices_list_car_model.txt
('Cruise Control', 'Cruise Control'),
....
('Bluetooth Handset', 'Bluetooth Handset'),
)
door_choices = (
('2', '2'),
...
('6', '6'),
)
car_title = models.CharField(max_length=255)
state = models.CharField(choices=state_choice, max_length=100)
city = models.CharField(max_length = 100)
...
...
no_of_owners = models.CharField(max_length = 100)
is_featured = models.BooleanField(max_length = 100)
created_date = models.DateTimeField(default=datetime.now, blank=True)
- Stop the server and migrate the changes to take effect
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 8000
- Go to localhost/admin, clickk on Cars and add a car to the DB
pip install django-ckeditor
pip install django-multiselectfield
Go to carsale/settings.py, and add the CKEditor:
installed_apps = [
...
'ckeditor',
]
- In cars/moldes.py, add
from ckeditor.fields import RichTextField
from multiselectfield import MultiSelectField
description = RichTextField()
features = MultiSelectField(choices=features_choices)
....
def __str_(self):
return self.car_title
- Make migration
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 8000
- In localhost/admin, Cars -> Add Cars. Fill the info of the cars with the files in car-photos directory, only 4 cars
- In cars/admin.py, copy from pages/admin.py
from django.contrib import admin
from .models import Car
from django.utils.html import format_html
# Register your models here.
class CarAdmin(admin.ModelAdmin):
def thumbnail(self, object):
return format_html('<img src="{}" width="40" style="border-radius: 50px;" />'.format(object.car_photo.url)) //modified in object.car_photo..
thumbnail.short_description = 'Car Image'
list_display = ('id', 'thumbnail', 'car_title', 'city', 'color', 'year', 'body_style', 'fuel_type', 'is_featured')
list_display_links = ('id', 'thumbnail', 'car_title') // make car title clickable
list_editable = ('is_featured',) // make featured editable in table
admin.site.register(Car, CarAdmin)
search_fields = ('id', 'car_title', 'city', 'model', 'body_style', 'fuel_type') //serach engine
list_filter = ('city', 'model', 'body_style', 'fuel_type') // filter engine
- In pages/views.py, line 6 onwards
from cars.models import Car
teams = Team.objects.all()
featured_cars = Car.objects.order_by('-created_date').filter(is_featured=True)
data = {
'teams' : teams,
'featured_cars': featured_cars,
}
- In templates/pages/home.html, line 185 - 242: group slide-item, 2nd group onwards to all those groups until slick-btn
<div class="slick-slide-item">
...
...
</div>
<div class="slick-btn">
- Add Loop in templates/pages/home.html, line 129
{% for car in featured_cars %}
<div class="slick-slide-item">
...
...
</div>
{% endfor %}
- Delete these lines in that group
<span class="del"><del>$805.00</del></span>
<br>
- In line 164
...ls.html">Lamborghini Huracán</a> => ...html">{{ car.car_title }}</a>
- In line 136
...<span>$780.00</span> => ...<span>${{ car.price }}}</span>
- In line 138
...src="img/car/car-1.jpg" ... => src="{{ car.car_photo.url }}" alt="car" style="min-height: 262px; max-height: 262px;">
- And below in the gallary remove one section just for 4 extrea images
href="img/car/car-1.jpg" => href="{{ car.car_photo_1 }}"
href="img/car/car-2.jpg" => href="{{ car.car_photo_2 }}"
href="img/car/car-3.jpg" => href="{{ car.car_photo_3 }}"
href="img/car/car-4.jpg" => href="{{ car.car_photo_4 }}"
- In line 168
..pin"></i>123 Kathal St. Tampa City, => ..pin"></i>{{car.state}}, {{car.city}}
- In line 172 - 177
<li>Petrol</li> => <li>{{car.fuel_type}}</li>
<li>4,000 km</li> => <li>{{car.miles}}</li>
<li>Manual</li> => <li>{{car.transmission}}</li>
<li>Sport</li> => <li>{{car.body_style}}</li>
<li>white</li> => <li>{{car.color}}</li>
<li>2020</li> => <li>{{car.year}}</li>
- Delete groups Line 273 - 337 onwards
<div class="col-lg-4 col-md-6">
...
</div>
- In pages/view.py, edit
def home(request):
teams = Team.objects.all()
featured_cars = Car.objects.order_by('-created_date').filter(is_featured=True)
all_cars = Car.objects.order_by('created_date')
data = {
'teams' : teams,
'featured_cars': featured_cars,
'all_cars': all_cars,
}
return render(request,'pages/home.html', data)
- Add the loop in templates/pages/home.html, line 208 - 274
{% for car in all_cars %}
<div class="col-lg-4 col-md-6">
...
</div>
{% endfor %}
- And in lines: 256, 260, 266, 269, 218, 221, 224,214
<a href="car-details.html">{{car.car_title}}</a>
<i class="flaticon-pin"></i>{{car.state}}, {{car.city}}
<p class="cartype">{{car.body_style}}</p>
<p class="price">{{car.price}}</p>
<span><i class="flaticon-way"></i></span>{{car.miles}} km
<span><i class="flaticon-calendar-1"></i></span>{{car.year}}
<span><i class="flaticon-manual-transmission"></i></span>{{car.transmission}}
<img class="d-block w-100" src="{{car.car_photo.url}}" alt="car" style="min-height: 262px; max-height: 262px;">
- In
<div class="car-magnify-gallery">
, line 238 (first photo)
<a href="{{car.car_photo.url}}" class="overlap-btn">
<i class="fa fa-expand"></i>
<img class="hidden" src="{{car.car_photo.url}}">
</a>
- Repeath fo the the other 4 photos:
{% if car.car_photo_1 %}
<a href="{{car.car_photo_1.url}}" class="hidden">
<img class="hidden" src="{{car.car_photo_1.url}}">
</a>
{% endif %}
- Line 144 , in featured_cars
<a href="{{car.car_photo.url}}" class="overlap-btn"> <!-- "{{ car.car_photo }}" -->
<i class="fa fa-expand"></i>
<img class="hidden" src="{{ car.car_photo.url }}">
- Also for the other 4 photos
{% if car.car_photo_1 %}
<a href="{{car.car_photo_1.url}}" class="hidden">
<img class="hidden" src="{{ car.car_photo_1.url }}">
</a>
{% endif %}
- In carzone/seeting.py, go to installed_apps, and seth the hummanize prize for cars (numbers notation)
INSTALLED_APPS = [
...
'django.contrib.humanize',
]
- In templates/home.html, line 136, add
<span>${{ car.price | intcomma }}</span>
- In line 4
{% block content %}
{% load humanize %}
{% load static %}
- Also hummanize km (kilometers), line 184
<li>{{car.miles | intcomma}} km</li>
- In the photo of latest cars, 229, 288 km
<span><i class="flaticon-way"></i></span>{{car.miles | intcomma }} km
<p class="price">{{car.price | intcomma}}</p>
- Add in cars/migrations/urls.py
path('<int:id>',views.car_detail,name='car_detail')
- And add in cars/migrations/views.py
def car_detail(request,id):
return render(request, 'cars/car_detail.html')
- Create the file templates\cars\car_detail.html, and modify line 175 of templates\pages\home.html
<a href="{% url 'car_detail' car.id %}">{{ car.car_title }}</a>
- From carhouse template, copy from car-details.html (line 128 - 140) to /templates/cars/car_detail.html
{% extends 'base.html' %}
{% block content %}
<!-- Sub banner start -->
<div class="sub-banner overview-bgi">
...
</div>
<!-- Sub Banner end -->
{% endblock %}
- From carhouse template, copy from car-details.html (line 142-547) to /templates/cars/car_detail.html, inside the block content, beneath the banner code just added
<!-- Car details page start -->
<div class="car-details-page content-area-6">
...
...
</div>
<!-- Properties details page end -->
- Add cars/migrations/views.py
from django.shortcuts import render, get get_object_or_404
from .models import Car
# Create your views here.
def cars(request):
return render(request, 'cars/cars.html')
def car_detail(request,id):
single_car = get_object_or_404(Car, pk=id)
data= {
'single_car': single_car
}
return render(request, 'cars/car_detail.html', data)
- In templates/car/car_detail.html, in line 4, add humanize
{% load humanize %}
and in 9 and 12, 28:{{single_car.car_title}}
- Also in line 30
<i class="flaticon-pin"></i>{{single_car.state}}, {{single_car.city}}
- And in line 34
<h3><span>{{single_car.price | intcomma}}</span></h3>
- For the lines 42, 45, 48, 51, 54
{{single_car.car_photo.url}}
{{single_car.car_photo_1.url}}
...
{{single_car.car_photo_4.url}}
- And in lines 44, 4 groups of images
{%if single_car.car._photo_1%}
<div class="item carousel-item" data-slide-number="1">
<img src="{{single_car.car_photo_1.url}}"" class="img-fluid" alt="slider-car">
</div>
{% endif %}
- For the slide, in line 70
<img src="{{single_car.car_photo.url}}" class="img-fluid" alt="small-car">
- Line 73, add the 4 groups
{% if single_car.car_photo_1 %}
<li class="list-inline-item">
<a id="carousel-selector-1" data-slide-to="1" data-target="#carDetailsSlider">
<img src="{{single_car.car_photo_1.url}}" class="img-fluid" alt="small-car">
</a>
</li>
{% endif %}
36. Display Single Car Data - Part 02 (8.4: http://localhost:8000/cars/3)
- In Description, remove it line 121, add instead
{{single_car.description | safe}}
- Delete 179-267 , 2 groups of:
<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12>
...
</div>
- Now delete almost all
<li>
and leave one<li>
group
<li>
Adaptive Cruise control --> {{single_car.features}}
</li>
- In line 160:
<li>
<span>Body Style:</span>Convertible --> <span>Color: </span>{{ single_color.color}}
</li>
- Fix vehicle overview buttom color in carzone/static/css/style.css, line 9767 - 9769: already fixed.
- In templates/pages/home.html, line 134, 179, 275, 278
<a href="car-details.html" class="car-img"> => "{% url 'car_detail' car.id %}"
<a href="car-details.html"> => "{% url 'car_detail' car.id %}"
<a href="car-details.html">Lamborghini Huracán</a> => "{% url 'car_detail' car.id %}"
<a href="car-details.html"> => "{% url 'car_detail' car.id %}"
- Make info of cars tab, for that keep just one group line 82 - 136
- From line 137 - 191 2nd group onwards, delete them and keep:
{% for car in cars %} <!-- add this for loop -->
<div class="col-lg-6 col-md-6">
...
</div>
{% endfor %}
<!-- Page navigation start
<div class="pagination-box p-box-2 text-center">
- In cars/view.py, edit
def cars(request):
cars = Car.objects.order_by('-created_date')
data = {
'cars': cars,
}
return render(request, 'cars/cars.html',data)
- In lines 31 & 34 of templates/cars/cars.html, add hummanize in line 5
{% block content %}
{% load humanize %}
<a href="car-details.html" class="car-img"> => "{{ url 'car_detail' car.id %}}"
<span>$780.00</span> => <span>${{ car.price | intcomma}}</span>
Line 42,44,46,47,49,50,52,53,55 and 56, repeat it
<a href="img/car/car-1.jpg" => <a href="{{car.car_photo.url}}"
... src="img/car/car-1.jpg" alt="car"> => ... src="{{ car.car_photo.url }}" alt="car">
{% if car.car_photo_1 %}
<a href="{{car.car_photo_1.url}}" class="hidden" >
<img class="hidden" src="{{car.car_photo_1.url}}">
</a>
{% endif %}
- In Line 65 to 79
...>Lamborghini Huracán</a> => >{{car.car_title}}</a>
.....</i>123 Kathal St. Tampa City => .....</i>{{car.state}}, {{car.city}}
- And in line 36
<img class="d-block w-100" src="{{ car.car_photo.url }}" alt="car"> =>
...car.car_photo.url }}" alt="car" style="min-height: 262px; max-height: 262px;">
- Add these lines in cars/view.py
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
def cars(request):
cars = Car.objects.order_by('-created_date')
paginator = Paginator(cars,3) //2 per page or 4 or 3
page = request.GET.get('page')
paged_cars = paginator.get_page(page)
data = {
'cars': paged_cars,
}
- In templates/cars/cars.html, line 95, wrap pagination
{% if cars.has_other_pages %}
<ul class="pagination">
...
</ul>
{% endif %}
- Add line 99 in
{%if cars.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{cars.previous_page_number}}"><i class="fa fa-angle-left"></i></a>
</li>
{% else %}
- Delete 109 and 110 and keep the code above, wrap it with an if/else clause (previous button)
{% if cars.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{cars.previous_page_number}}"><i class="fa fa-angle-left"></i></a>
</li>
{% else %}
- For next button or arrow , line 117
{% if cars.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{cars.next_page_number}}"><i class="fa fa-angle-right"></i></a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link"><i class="fa fa-angle-right"
- In cars/urls.py
urlpatterns = [
path('', views.cars, name='cars'),
path('<int:id>',views.car_detail,name='car_detail'),
path('search', views.search, name='search'),
]
- Add In cars/views.py
def search(request):
cars= Car.objects.order_by('-created_date')
data={
'cars': cars,
}
return render(request, 'cars/search.html', data)
-
Create templates\cars\search.html, and add
<h2> Search</h2>
-
Prove if it is working in localhost:8000/cars/search
-
Note: jump to the step 40
- Copy
<!-- Full Page Search -->
from templates/base.html to templates/pages/home.html and modify like from line 357
<!-- Full Page Search --> <div id="full-page-search"> <button type="button" class="close">×</button> <form action="{% url 'search' %}" class="search-header"> <input type="search" value="" placeholder="type keyword(s) here. Eg: audi, benz etc" name='keyword'/> <button type="submit" class="btn btn-sm button-theme">Search</button> </form> </div>
- Prove in
http://localhost:8000/
, click on search type Benz, should take you to the search.html page - From the template carhouse/search.html, copy the Banner group to templates/cars/serach.html, and lines 147-659
{% extends 'base.html' %} {% block content %} {% load humanize %} <!-- Banner start --> ... <!-- Banner end --> <!-- Search box 3 start --> ... ... <!-- Featured car end --> {% endblock %}
- Now, delete the groups below
<div class="col-lg-4 col-md-6">
, line 187-526 and add the for loop, line 120-187
{% for car in cars %} <div class="col-lg-4 col-md-6"> ... {% endfor %}
- These loops are raplaced by the loop of templates/pages/home.html
{% for car in cars %} <!-- cars* not all all_cars --> <div class="col-lg-4 col-md-6"> ... ... {% endfor %}
- Copy