Demo Part 1
Step 1 Installation
Make sure that you have installed Python 3.5.x, Git and Editor (atom,sublime text or visual code). Before starting our project we setup virtual environment, activate it and then install django using
$ pip install django
Once we install django and any other required package, it is good idea to save that in a requirements.txt
file.
$ pip freeze > requirements.txt
Step 2 Start Project
Start Django project
$ django-admin startproject djangocupcakeshop
Step 3 Change Settings
After creating the project, we have to change TIME_ZONE
in settings.py
file. You can find it under djangocupcakeshop/djangocupcakeshop/settings.py
folder. It depends on where your site is hosted. For Seoul, we will change it the following.
TIME_ZONE = "Asia/Seoul"
To setup the correct configuration for static and media files (images, css, javascript), add the following lines below STATIC_URL
.
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
MEDIA_ROOT and MEDIA_URL setup the path for uploaded images and files.
We are all set for creating our database tables and checking our project in the browser. Run the following two commands in terminal/command prompt.
$ python manage.py migrate
$ python manage.py runserver
Open the browser and go to the link : http://127.0.0.1:8000
Step 4 Django App/Model
Relevant git branch
model
a. We create the app name menu
and add it to settings.py
file in the section INSTALLED_APPS
$ manage.py startapp menu
settings.py
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'menu',
)
Demo starts from here
b. We are going to create a model for our menu app. From here onwards, start following me on and refer to tutorial for references. The required fields for our model class Cupcake
are name,rating,price,image,writer and createdAt
. You also have to install Pillow
package which is required for ImageField
. so install it by executing
(myvenv) $ pip install Pillow
and then update requirements file by
(myvenv) $ pip freeze > requirements.txt
If there is an error in Windows installation while installing Pillow. Use
pip install Pillow==3.0.0
The import part will go first
from django.contrib.auth.models import User
from django.utils import timezone
followed by model Class
class Cupcake(models.Model):
name = models.CharField(max_length=200)
price = models.CharField(max_length=20)
rating = models.FloatField()
image = models.ImageField(upload_to='images/cakes')
writer = models.ForeignKey(User)
createdAt = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
c. After creating model, we create actual tables in database by executing following commands
$ python manage.py makemigrations menu
$ python manage.py migrate
By running makemigrations, you’re telling Django that you’ve made some changes to your models (in this case, you’ve made new ones) and that you’d like the changes to be stored as a migration. At this point after
makemigrations
you can test your model by executingpython manage.py test
. We have provided a test case already for your convenience! In Summarymakemigrations
command make migrations for changes in model andmigrate
actually applies those changes in database
Step 5 Django Admin
Relevant git branch
admin
a. Register our model in admin so that we can add cupcakes from admin site. Open menu/admin.py
file and add the following.
from django.contrib import admin
from .models import Cupcake
admin.site.register(Cupcake)
b. Now its time to add few cupcakes from the site. But in order to do so, you would need admin account. Create it by executing following command in terminal/command prompt and follow the instructions.
python manage.py createsuperuser
Start developement server again python manage.py runserver
. Visit http://127.0.0.1:8000/admin to login and add cupcakes!
Step 6 Django Urls
Relevant git branch
django-urls
a. We have to point a url towards our home page. Firstly, we will point the home page URL to our menu app. Add following to djangocupcakeshop/urls.py
.
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'', include('menu.urls',namespace='menu')),
]
b. Secondly, we will point URL to corresponding view
function in our menu app. Create a file in menu
directory and name it urls.py
. Add following code
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.cupcake_list,name="cupcake_list"),
]
For now if you run your server and visit the home page, It will show an error. If you pay attention to the error, it is about absence of views function cupcake_list
. Don't worry, we will create this function in the next step.
Step 7 Django Views
In Django, web pages and other content are delivered by views. Each view is represented by a simple Python function. Django will choose a view by examining the URL that’s requested. We have already added url
for home page in previous step. We are going to add our first view function cupcakes_list
in menu/views.py
file.
from django.shortcuts import render
from . import models
def cupcake_list(request):
return render(request,"menu/list.html",{})
Start your server and visit the home page http://127.0.0.1:8000 Oops! You will come across following error!. Let's fix this in next step.
Step 8 Django Templates
a. If you look at the error in previous step, you will notice that is complaining about missing template menu/list.html
. Django template is an html page where you show your data to user which was stored in database. First, create a directory called templates in your menu directory. Django will look for templates in there.
Within the templates directory you have just created, create another directory called menu, and within that create a file called list.html. In other words, your template should be at menu/templates/menu/list.html. We will use bootstrap for creating html page. You can find some example templates here. To customize our template we created a style.css
file and added few nice images! You can find free cupcake images from here. For adding static files, create a folder static
in menu directory. Then create a menu folder. In menu folder, create two folders to hold our css and image files. So your directory sturcture for css will be menu/static/menu/css
and images menu/static/menu/images
list.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django Cupcake Shop</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static 'menu/css/style.css' %}">
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<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" href="/">Django Cupcake Shop</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Sort by <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Highest</a></li>
<li><a href="#">Lowest</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="container" >
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron title text-center" style="background-image: url({% static 'menu/images/cupcake_cover.jpg' %});">
<h1 class="title">Cupcakes and High Fives!</h1>
<p>Django Girls Seoul welcomes you!</p>
<p>Lets build an awesome Django site together</p>
<p>
<a class="btn btn-lg btn-primary" href="https://github.com/DjangoGirlsSeoul/djangocupcakeshop" role="button">Source Code »</a>
</p>
</div>
</div> <!-- /container -->
<div class="container">
<h2 class="text-center">Choose your favorite Cupcake!</h2>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/chocolate_cupcake.jpg' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Chocolate Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/vanilla_cupcake.jpeg' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Vanilla Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/blueberry_cupcake.png' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Blueberry Cookie Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="text-muted">Pycon 2016 Tutorial.</p>
</div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" ></script>
</body>
</html>
We also need a css file for minor adjustments in the template. Create file style.css
in menu/static/menu/css
folder. Add following contents to css file
style.css
@import url(http://fonts.googleapis.com/css?family=Raleway:400,800|Roboto+Slab:300);
body {
font-family: "Roboto Slab","Helvetica", "Arial", sans-serif;;
padding-top: 70px;
}
.card {
margin: 2rem auto;
}
.image {
width: 100%;
height: 250px;
padding-bottom: 50%;
transition: 0.1s linear;
background-image: url(http://www.freeallimages.com/wp-content/uploads/2014/09/space-cat-wallpaper-5.jpg);
background-size: cover;
background-position: center center;
}
.card-title {
margin-bottom: 1rem;
font-weight: 900;
}
.jumbotron {
height: 450px;
}
.title {
color: white !important;
}
.footer {
position: relative;
bottom: 0;
width: 100%;
margin-top: 150px;
text-align: center;
/* Set the fixed height of the footer here */
height: 60px;
background-color: #f5f5f5;
}
.footer > .container {
padding-right: 15px;
padding-left: 15px;
}
.text-muted {
margin-top: 20px;
}
.glyphicon
{
color:#FF5252;
}
/* navbar */
.navbar-default {
border-color: #FF5252;
}
a {
color: #FF5252;
}
In menu/static/images
folder, add three cupcakes images and make sure that names are same as the ones in list.html
file.
b. We have to create a detail page for our cupcake
where we can show more information such as price and user who uploaded it. Let's create a detail.html
in the same folder as list.html
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django Cupcake Shop</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static 'menu/css/style.css' %}">
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<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" href="/">Django Cupcake Shop</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Sort by <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Highest</a></li>
<li><a href="#">Lowest</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-3">
<div class="card">
<ul class="list-group">
<li class="list-group-item"><span class="glyphicon glyphicon-tag"></span> <strong>Chocolate Cupcake</strong></li>
<li class="list-group-item"><span class="glyphicon glyphicon-usd"></span> 3.00</li>
<li class="list-group-item"><span class="glyphicon glyphicon-pencil"></span> John</li>
<li class="list-group-item"><span class="glyphicon glyphicon-calendar"></span> 3rd June, 2015</li>
<li class="list-group-item">
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
</li>
<li class="list-group-item">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Order
</button>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Chocolate Cupcake</h4>
</div>
<div class="modal-body">
Complete this website to get your Cupcake!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="text-muted">Pycon 2016 Tutorial.</p>
</div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" ></script>
</body>
</html>
C. We can observe that both list.html
and base.html
share lots of common html such as header and footer. Django allows us to create base
template and extend other templates from it. Create a base.html
in same folder with list.html
. And put the list.html
contents in it. Delete the part from <div class="container">
until just before the footer
and replace with
{% block content %}
{% endblock %}
After replacing, your base.html
will look like as follows :
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django Cupcake Shop</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static 'menu/css/style.css' %}">
</head>
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<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" href="/">Django Cupcake Shop</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Sort by <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Highest</a></li>
<li><a href="#">Lowest</a></li>
</ul>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
{% block content %}
{% endblock %}
<footer class="footer">
<div class="container">
<p class="text-muted">Pycon 2016 Tutorial.</p>
</div>
</footer>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" ></script>
</body>
</html>
Now we have to connect base template with list and detail template.
list.html
{% extends 'menu/base.html' %}
{% load staticfiles %}
{% block content %}
<div class="container">
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron title text-center" style="background-image: url({% static 'menu/images/cupcake_cover.jpg' %});">
<h1 class="title">Cupcakes and High Fives!</h1>
<p>Django Girls Seoul welcomes you!</p>
<p>Lets build an awesome Django site together</p>
<p>
<a class="btn btn-lg btn-primary" href="https://github.com/DjangoGirlsSeoul/djangocupcakeshop" role="button">Source Code »</a>
</p>
</div>
</div> <!-- /container -->
<div class="container">
<h2 class="text-center">Choose your favorite Cupcake!</h2>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/chocolate_cupcake.jpg' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Chocolate Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/vanilla_cupcake.jpeg' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Vanilla Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/blueberry_cupcake.png' %});"></div>
</div>
<div class="card-block">
<h4 class="card-title text-center">Blueberry Cookie Cupcake</h4>
<p class="card-text text-center">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
</p>
<a href="#" class="btn btn-default btn-lg btn-block">View</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
detail.html
{% extends 'menu/base.html' %}
{% load staticfiles %}
{% block content %}
<div class="container">
<h2 class="text-center">Order Cupcake</h2>
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4 col-md-offset-2 col-md-lg-2">
<div class="card">
<div class="card-img-top">
<div class="image" style="background-image: url({% static 'menu/images/chocolate_cupcake.jpg' %});"></div>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-3 col-lg-3">
<div class="card">
<ul class="list-group">
<li class="list-group-item"><span class="glyphicon glyphicon-tag"></span> <strong>Chocolate Cupcake</strong></li>
<li class="list-group-item"><span class="glyphicon glyphicon-usd"></span> 3.00</li>
<li class="list-group-item"><span class="glyphicon glyphicon-pencil"></span> John</li>
<li class="list-group-item"><span class="glyphicon glyphicon-calendar"></span> 3rd June, 2015</li>
<li class="list-group-item">
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
</li>
<li class="list-group-item">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Order
</button>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Chocolate Cupcake</h4>
</div>
<div class="modal-body">
Complete this website to get your Cupcake!
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
{% endblock %}
Start developement server go to the link : http://127.0.0.1:8000 to see the list template!
Move to next part of Demo