ISYS 618 Application Development: Fitzroy Catholic Bookshop Project

Verified

Added on  2023/06/12

|15
|4680
|337
Project
AI Summary
This project details the design, development, and testing of a website for the Fitzroy Catholic Bookshop. Built using XHTML, CSS, Bootstrap, and Python/Django, the application allows users to search for items by publisher, title, category, and price range. The project includes server-side scripting, database interaction, and a test script (tests.py) with dummy data to assert expected results. Key components include models (Product, Image), forms (ProductForm, SearchForm), views for handling user requests, and templates for rendering the user interface. The website incorporates a clean design with a focus on functionality and user experience. Access the full project and other solved assignments on Desklib.
Document Page
Application Development
NAME
COURSE
UNIVERSITY/AFFILIATION
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
Introduction
The aim of this task is to create design, develop and test a website for the Fitzroy Catholic Bookshop.
The user can search for specific items based on the publisher, title, category, and price range. The web
project has been designed using xhtml thus making it compatible with almost all broswers regardless of
the platform or device. CSS and bootstrap have been used for styling and conditional styling while
python/django has been used to cater for server side requirement.
Additional Information.
The images used in the web project have been downloaded from www.userlogos.org (e.g
http://www.userlogos.org/files/logos/euphonicnight/Lib1.png) and usage of the images has been
acknowledged wherever they have been used. Images of my own were also uploaded to
https://image.ibb.co/, thus the <img> tags reference to that site in most cases.
“Fitzroy Catholic Bookshop” has been used as the company title through out the website.
So as to know the currently active page, the following peace of code has be used.
<meta charset="utf-8"> {% if title %}
<!-- if the var title has not null, append the (Current page) title to out Main Title -->
<title>Fitzroy Catholic Bookshop | {{title}}</title>
{% else %}
<title> Fitzroy Catholic Bookshop </title>
When the one browses to a page lets say the search results page, a “Home | Search Results” will be
displayed on top right side of that page.
The Look and Feal has been kept quite simple with the main content area background and Pale yellow
background for footers.
The functionality of the website has been tested and works as expected. A test script (tests.py) has been
includes. It contains dummy data and aims to assert that the results are as expected given predetermine
queries depicting real user actions.
Document Page
Python Code.
admin.py
from django.contrib import admin
from .models import Image,Product
#Register the models.
admin.site.register(Image)
admin.site.register(Product)
forms.py
from django import forms
from . models import Product
CATEGORY_CHOICES= [
('book', 'Book'),
('audio book', 'Audio Books'),
('video', 'Video'),
('music', 'Music'),
]
PUBLISHER_CHOICES= [
('franciscan media', 'Franciscan Media'),
('Penguins', 'Penguins'),
('st pauls publication', 'St Pauls Publication'),
('marvels', 'Marvels'),
('harper collins', 'Harper Collins'),
]
class ProductForm(forms.Form):
'''
New Products form
'''
title = forms.CharField(label='Title',max_length = 140)
isbn = forms.CharField(label='ISBN',max_length = 64)
category = forms.CharField(label='Category', widget=forms.Select(choices=CATEGORY_CHOICES))
author = forms.CharField(label='Author',max_length = 64)
publisher = forms.CharField(label='Publisher', widget=forms.Select(choices=PUBLISHER_CHOICES))
price = forms.IntegerField(label='price')
quantity = forms.CharField(label='Quantity',max_length = 64)
image = forms.ImageField(label='Image',max_length = 64)
class SearchForm(forms.Form):
'''
Create the search form
'''
min_price = forms.IntegerField(label='Min price')
max_price = forms.IntegerField(label='Max price')
category = forms.CharField(label='Category', widget=forms.Select(choices=CATEGORY_CHOICES))
publisher = forms.CharField(label='Publisher', widget=forms.Select(choices=PUBLISHER_CHOICES))
Document Page
apps.py
from django.apps import AppConfig
#Name of the Web Application
class FitzroybookshopConfig(AppConfig):
name = 'fitzroybookshop'
models.py
from django.db import models
class Product(models.Model):
'''
Products object
'''
title = models.CharField(max_length=140)
isbn = models.CharField(max_length=64)
category = models.CharField(max_length=64)
author = models.CharField(max_length=64)
publisher = models.CharField(max_length=64)
price = models.IntegerField( null = True)
quantity = models.IntegerField(null = True)
image = models.ImageField(upload_to = 'images/' ,null = True)
def __str__(self):
return self.title
def save_prod(self):
self.save()
def delete_prod(self):
self.delete()
@classmethod
def find_prod(cls,name):
found_prods = cls.objects.filter(username__icontains = name).all()
return found_prods
@classmethod
def search_prod(cls,min_price,max_price,category,publisher):
'''
return a list of objects which satisfy user query
'''
list_out =[]
requested_products = cls.objects.filter(category = category,publisher = publisher).all()
for item in requested_products:
if item.price>= min_price and item.price <= max_price:
list_out.append(item)
return list_out
class Image(models.Model):
'''
image objects
'''
name = models.CharField(max_length= 30)
image = models.ImageField(upload_to = 'images/' ,null = True)
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
views.py
from django.shortcuts import render
from django.shortcuts import render,redirect
from . models import Product
from . forms import ProductForm,SearchForm
def home(request):
return render(request, 'home.html')
def maintenance(request):
form = ProductForm()
if request.method == 'POST':
form = ProductForm(request.POST,request.FILES)
if form.is_valid():
title = form.cleaned_data['title']
isbn = form.cleaned_data['isbn']
category = form.cleaned_data['category']
author = form.cleaned_data['author']
publisher = form.cleaned_data['publisher']
price = form.cleaned_data['price']
quantity = form.cleaned_data['quantity']
image = form.cleaned_data['image']
prod = Product(title = title, isbn =isbn ,category =category,author =author ,publisher = publisher ,price =
price,quantity = quantity ,image = image)
prod.save()
form = ProductForm()
else:
form = ProductForm()
return render(request, 'maintenance.html',{"form":form})
def search(request):
form = SearchForm()
if request.method == 'POST':
form = SearchForm(request.POST,request.FILES)
# Ensure the data meets the criteria set in forms.py
if form.is_valid():
min_price = form.cleaned_data['min_price']
max_price = form.cleaned_data['max_price']
publisher = form.cleaned_data['publisher']
category = form.cleaned_data['category']
requested_prods = Product.search_prod(min_price,max_price,category,publisher)
return render(request, 'results.html',{"form":form,"requested_prods":requested_prods})
else:
form = ProductForm()
return render(request, 'search.html',{"form":form})
def map(request):
title = 'Site Map'
return render(request, 'map.html',{"title":title})
Document Page
tests.py
from django.test import TestCase
from . models import Product
class ProductTestClass(TestCase):
'''
Test the Product model
'''
def setUp(self):
'''
Setup function for the tests
'''
self.prod = Product(title = 'test title1',isbn = 'ISBN 0000',category ='Book',author = 'test author1',publisher = 'test
publisher1',price = 90,quantity = 10,image ='images/img.png')
def test_instance(self):
'''
Test instanciation of products
'''
self.assertTrue(isinstance(self.prod,Product))
def test_save_prod(self):
'''
Test the save function of model image
'''
self.prod.save_prod()
all_prods= Product.objects.all()
self.assertTrue(len(all_prods)>0)
def test_delete_prod(self):
'''
Test the delete_prod function
'''
self.prod.save_prod()
new_prod = Product(title = 'test title2',isbn = 'ISBN 1111',category ='Video',author = 'test artist',publisher = 'test
publisher2',price = 10,quantity = 10,image ='images/vid.mpeg')
new_prod.save_prod()
self.prod.delete_prod()
all_prods = Product.objects.all()
self.assertTrue(len(all_prods)==1)
def test_search_prod(self):
'''
Test the search_prod function
'''
self.prod.save_prod()
new_prod = Product(title = 'test title2',isbn = 'ISBN 1111',category ='Book',author = 'test artist',publisher = 'test
publisher1',price = 90,quantity = 10,image ='images/vid.mpeg')
new_prod.save_prod()
all_prods = Product.search_prod(80,100,'Book','test publisher1')
self.assertTrue(len(all_prods) ==2)
Document Page
urls.py
from django.conf.urls import url
from . import views
from django.conf import settings
from django.conf.urls.static import static
# Allow the app to make use of the static paths
from django.conf import settings
from django.conf.urls.static import static
#Define the Links to various pages on the site
urlpatterns=[
url('^$',views.home,name = 'Home'),
url('^search/',views.search,name = 'Search'),
url('^maintenance/',views.maintenance,name = 'Maintenance'),
url('^site/map',views.map,name = 'Site_Map'),
]
if settings.DEBUG:
urlpatterns+= static(settings.MEDIA_URL, document_root = settings.MEDIA_ROOT)
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
TEMPLATES / XHTML CODE
base.html
{% load bootstrap3 %} {% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> {% if title %}
<title>Fitzroy Catholic Bookshop | {{title}}</title>
{% else %}
<title> Fitzroy Catholic Bookshop </title>
{% endif %} {% block styles %} {% bootstrap_css %}
<link rel="stylesheet" href="{% static 'css/base.css' %}"> {% endblock %}
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit-icons.min.js"></script>
</head>
<body>
{% include "navbar.html" %} {% block content %} {%endblock%} {% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
{% bootstrap_javascript %} {% endblock %}
</body>
home.html
{% load staticfiles%}
{% load bootstrap3 %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> {% if title %} <!-- if the var title has not null, append the (Current page) title to out Main Title
-->
<title>Fitzroy Catholic Bookshop | {{title}}</title>
{% else %}
<title> Fitzroy Catholic Bookshop </title>
{% endif %} {% block styles %} {% bootstrap_css %}
<link rel="stylesheet" href="{% static 'css/base.css' %}"> {% endblock %}
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.42/js/uikit-icons.min.js"></script>
</head>
<body >
<!-- Add navbar.html to this template -->
{% include "navbar.html" %} {% block content %}
<!-- Landing Section -->
Document Page
<div class="container" >
<h5 style="text-align:left;"><span id="bread_title" >Navigation&nbsp;:&nbsp;&nbsp;</span> <span
id="bread">Home -></span></h5>
<hr>
<div class="col-md-12" id="call_to_action" >
<div class="row">
<div class="col-md-6">
<h4 style="text-align:left;color:#5e12aa;font-weight:bolder;">About Us.</h4>
<div id="description" style="border-radius:5%; padding:20px;margin:30px;background-color: #ffffff;
opacity: .4;color:black;">
<h3 style="color:black;margin:30px;">
Fitzroy Catholic Bookshop is a one-stop place for all Best Sellers.
</h3>
<h4>Discover them all at the comfort of your home!</h4>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-4" style="background-color:ffffff;text-align:center;">
<h5 style="color:#5e12aa;font-weight:bolder;font-size:30px;" >Search For A Product </h5>
<button class="btn btn-primary" style="margin-bottom:20px;padding-left:50px;padding-
right:50px;">Search</button>
</div>
<div class="col-md-4"></div>
</div>
</div>
<!-- Contact us section -->
<div class="col-md-12" style="background-color:#fffba9;">
<div class="col-md-6">
<h3 style="margin-top:40px; text-align:center;font-weight:bolder;color:#5e12aa;">Contact Us</h3>
<!-- description for contact us -->
<h4 style="margin-top:50px; text-align:center;font-weight:bolder;">Your needs and user experience is at
heart.
We will give you feedback in less than 48 hours</h4>
</div>
<div class="col-md-6">
<div class="panel" style="border-color:#3c11cb; padding:20px; margin:30px;">
<!-- the contact us form -->
<form>
<div class="form-group">
<label >Name</label>
<input type="text" class="form-control" placeholder="Name">
<label >Email address</label>
<input type="email" class="form-control" aria-describedby="emailHelp" placeholder="Email">
<label >Message</label>
<input type="textfield" class="form-control" placeholder="Message">
<small id="emailHelp" class="form-text text-muted">Your Email is never shared with anyone
else..</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<!-- End of contact us -->
Document Page
</div>
</div>
</div>
<!-- Sitemap section: for fitzroy library -->
<div class="col-md-12">
<div class="col-md-6">
<img style="width:600px; margin-top:30px;margin-bottom:30px;"
src="data:image/jpeg;base64,/9j/4A...b/lYujjqCm/57koLidGj8KjQ/uV7w/wCpa/8ASJcED//Z"/>
</div>
<div class="col-md-6">
<h3 style="margin-top:40px;font-weight:bolder;color:#5e12aa;">Locate Us</h3>
<h4>Use the sitemap to the left to locate Us.</h4>
</div>
</div>
<!-- Footer section-->
<div class="col-md-12" style="background-color:#fffba9;">
<!-- Social media-->
<div class="col-md-12" style="background:#fffba9;padding-top:20px;border-color:#5e12aa;">
<div class="col-md-2">
<h4 style="height:150px;width:150px;">Facebook<img src="data:image/png;base64,iVB...YII="/> </h4>
</div>
<div class="col-md-2">
<p style="margin-top:30px;">Join Us On Facebook to stay up to date with out new arrivals
</div>
<div class="col-md-2">
<h4 style="height:150px;width:150px;">Twitter <img src="https://encrypted-tbn0.gstatic.com/images?
q=tbn:ANd9GcS_Cl7FZnFqvBrKZWB4uiK1I2ckryTAb_3FgWtGBzBMHwZLuzOh"/></h4>
</div>
<div class="col-md-2">
<p style="margin-top:30px;"> Join Us on Twitter get instant updates answers to your queries
</div>
<div class="col-md-2">
<h4 style="height:150px;width:150px;">Google + <img
src="data:image/jpeg;base64,/9j/4AAQSkZJ.QP/Z"/></h4>
</div>
<div class="col-md-2">
<p style="margin-top:30px;">Our Community on Google + is waiting for you. Join Us.</p>
</div>
</div>
<div class="col-md-12" style="margin-top:30px; margin-bottom:30px;">
<div class="col-md-4"></div>
<div class="col-md-4">
<p>
Are you stranded on how to find what you are looking for? Whenever you have forgotten the name of
what you are looking for, or when spoiled of choice when it comes to choosing what to buy, our community on social
media will be more than glad to help you out. Join Us today and get all the benefits at no extra cost.
</p>
</div>
<div class="col-md-4"></div>
</div>
</div>
<!-- End Of Footer Section -->
</div>
tabler-icon-diamond-filled.svg

Paraphrase This Document

Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser
Document Page
{%endblock%} {% block scripts %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
{% bootstrap_javascript %} {% endblock %}
</body>
maintenance.html
{% extends 'base.html'%}{% load staticfiles%}{% load bootstrap3 %}
{% block content %} {{block.super}}
<h5 style="text-align:right;"><span id="bread_title" >Navigation&nbsp;:&nbsp;&nbsp;</span> <span id="bread">Home
| Maintenance</span></h5>
<hr>
<div class="container">
<div class="col-xs-0 col-sm-0 col-md-5 col-lg-5 col-xl-5">
<h3 style="margin-top:50px;text-align:left;color:#5e12aa;font-weight:bolder;">Adding Items To Catalogue</h3>
<p style="margin-top:50px;">Fill in the form with the item's information to add it to the bookshop's database.
Please ensure that prices are numeric value and not words.
</p>
</div>
<div class="col-xs-12 col-sm-12 col-md-7 col-lg-7 col-xl-7">
<form method="post" enctype="multipart/form-data">
{% csrf_token %} {% bootstrap_form form%}
<input type="submit" class="btn btn-primary btn-sm" value="Add to Catalogue" style="margin-bottom:20px;">
<input type="hidden" name="next" value="{{next}}">
</form>
</div>
map.html
{% extends 'base.html'%}{% load staticfiles%}{% load bootstrap3 %}
{% block content %} {{block.super}}
<h5 style="text-align:right;"><span id="bread_title" >Navigation&nbsp;:&nbsp;&nbsp;</span> <span id="bread">Home
| Site Map</span></h5>
<hr>
<div class="container">
<div class="col-xs-0 col-sm-0 col-md-3 col-lg-3 col-xl-3" style="background-color:#fffba9;"></div>
<div class="col-xs-12 col-sm-12 col-md-6 col-lg-6 col-xl-6" style="background-color:#fffba9;">
<div >
<img style="width:500px;height:300px;" src="https://image.ibb.co/ge1RT8/map.png" alt="Site_Map"
border="0">
</div>
</div>
<div class="col-xs-0 col-sm-0 col-md-3 col-lg-3 col-xl-3" style="background-color:#fffba9;"></div>
navba.html
{% load bootstrap3 %}{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="path/to/font-awesome/css/font-awesome.min.css">
Document Page
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="{% static 'css/navbar.css' %}">
</head>
<body>
<nav id="nav_body" class="navbar navbar-inverse" id="nav_body" >
<div class="col-md-5" >
<image src="http://www.userlogos.org/files/logos/euphonicnight/Lib1.png" id ="logo_image"
style="width:300px;height:150px;"/>
</div>
<div class="col-md-7">
<h1 id ="title">Fitzroy Catholic Bookshop</h1>
<h5 id="menu_bar" style="text-align:center;">
<a href="{%url 'Home'%}">Home</a> &nbsp;&nbsp;|&nbsp;&nbsp;
<a href="{%url 'Site_Map'%}">Site Map</a>&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="{%url 'Search'%}">Search</a>&nbsp;&nbsp;|&nbsp;&nbsp;
<a href="{%url 'Maintenance'%}">Maintenance</a></h5>
</div>
</nav>
</div>
</body>
</html>
results.html
<!-- inherit from base template -->
{% extends 'base.html'%}{% load staticfiles%}{% load bootstrap3 %}
{% block content %} {{block.super}}
<h5 style="text-align:center;"><span id="bread_title" >Navigation&nbsp;:&nbsp;&nbsp;</span> <span
id="bread">Home | Search Results</span></h5>
<hr>
<div class="container">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
<div class="panel" style="padding:20px;">
<!-- Return Results of items matching user query -->
{% if requested_prods %}
<h3>{{ requested_prods|length }} products found that match your search</h3>
{% else %}
<h3> Oops! No items match your search</h3>
{% endif %}
<!-- Loop though the result and displays them within the template -->
{% for item in requested_prods %}
<div class="panel" style="background-color:#fffba9; padding:20px;">
<h4 style="margin:10px;">{{item.title}}</h4>
<img src="{{item.image.url}}" class="img-responsive" alt='Image'> <p>Author:&nbsp;{{item.author}} &nbsp;
Publisher:&nbsp;{{item.publisher}}&nbsp; Price: &nbsp;{{item.quantity}}</p></image>
</div>
{% endfor %}
</div>
</div>
chevron_up_icon
1 out of 15
circle_padding
hide_on_mobile
zoom_out_icon
[object Object]