Building a Food Delivery App With Django and Python 3: Part 1 Getting Started and Setting Up the App

LegionScript
7 min readOct 20, 2020

Video Tutorial

Code on Github

In this tutorial series, we will build a Food Delivery Application using Python 3 and Django. In this first tutorial we are going to set up the project and build a simple index and about page. Like the previous tutorials we are not going to go through all of the basics of Django, it’s assumed that you have a basic understanding of those concepts already. We are going to use various tools including an API to handle using a map when determining address location for the delivery. There will be two sides to this application, one will be the public customer side where users can place food orders and there will also be a restaurant side where the restaurant can manage and fulfill the orders.

Let’s begin by creating a django project and a couple apps using these commands:

virtualenv env
django-admin startproject fooddelivery
cd fooddelivery
python3 manage.py startapp customers
python3 manage.py startapp restaurant
python3 manage.py migrate
python3 manage.py createsuperuser

These commands will create everything we will need, you will need to fill out the information for the super user after entering that command. We are creating two apps, one for the customer side and one for the restaurant management side. Let’s add these apps to our settings.py file:

INSTALLED_APPS = [
'customer',
'restaurant',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

Building the Index and About Pages

Now let’s build the first two pages for this application. Let’s create two views in our views.py for these pages. We will use the generic View class for these:

from django.shortcuts import render
from django.views import View
class Index(View): def get(self, request, *args, **kwargs):
return render(request, 'customer/index.html')
class About(View): def get(self, request, *args, **kwargs):
return render(request, 'customer/about.html')

With the generic View class, we will need to create methods to handle what will happen with each HTTP request the view will need to handle. In this case, we are only going to handle GET requests for now. All we are doing is rendering an HTML template when the user sends a GET request to the server.

Now let’s build the HTML files. Let’s start with the base.html that every other template will inherit from:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
<!-- Google Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap">
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Material Design Bootstrap -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet">
<title>Deliver</title>
</head>
<body>
{% include 'customer/navigation.html' %}
{% block content %}
{% endblock content %}
{% include 'customer/footer.html' %}

<!-- JQuery -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Bootstrap tooltips -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.4/umd/popper.min.js"></script>
<!-- Bootstrap core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<!-- MDB core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/js/mdb.min.js"></script>
</body>
</html>

We are setting up a basic HTML file with mdBootstrap and creating a content block. We are also inlcluding a file that will hold our site’s navigation. Let’s go ahead and build that now as well:

<nav class="navbar navbar-expand-lg navbar-dark indigo">
<a class="navbar-brand" href="{% url 'index' %}">Deliver</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText"
aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="{% url 'about' %}">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Menu</a>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Place an Order!</a>
</li>
</ul>
</div>
</nav>

We will match the URLs to the names of the URL patterns that we will create at the end of this tutorial. Now with the HTML set up, let build the index.html:

{% extends 'customer/base.html' %}{% block content %}
<div class="container mb-5">
<div class="row justify-content-center mt-5">
<div class="col-md-8 col-sm-12 offset-md-1 p-4 text-center">
<h1>Online Food Delivery Service</h1>
</div>
</div>
<div class="row justify-content-center mt-1">
<div class="card col-md-5 col-sm-12 offset-md-1 p-4 text-center">
<h2>Place an Order!</h2>
<button class="btn btn-outline-primary">Order Now!</button>
</div>
</div>
</div>
{% endblock content %}

Here we are extending the base.html template and creating a heading and a button within the content block we defined in our base.html. For now this button won’t do anything, in the future we will add some functionality to it. Let’s build the about.html:

{% extends 'customer/base.html' %}{% block content %}
<div class="container mb-5">
<div class="row justify-content-center mt-5">
<div class="col-md-10 col-sm-12 offset-md-1 p-4 text-center">
<h1>About Us!</h1>
</div>
</div>
<div class="row justify-content-center mt-1">
<div class="col-md-10 col-sm-12 offset-md-1 p-4 text-center">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem.</p>
<p>Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, quis gravida magna mi a libero. Fusce vulputate eleifend sapien. Vestibulum purus quam, scelerisque ut, mollis sed, nonummy id, metus. Nullam accumsan lorem in dui. Cras ultricies mi eu turpis hendrerit fringilla. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; In ac dui quis mi consectetuer lacinia. Nam pretium turpis et arcu. Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. Sed aliquam ultrices mauris. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Praesent adipiscing. Phasellus ullamcorper ipsum rutrum nunc. Nunc nonummy metus. Vestibulum volutpat pretium libero. Cras id dui. Aenean ut eros et nisl sagittis vestibulum.</p>
<p>Nullam nulla eros, ultricies sit amet, nonummy id, imperdiet feugiat, pede. Sed lectus. Donec mollis hendrerit risus. Phasellus nec sem in justo pellentesque facilisis. Etiam imperdiet imperdiet orci. Nunc nec neque. Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent congue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed aliquam, nisi quis porttitor congue, elit erat euismod orci, ac placerat dolor lectus quis orci. Phasellus consectetuer vestibulum elit. Aenean tellus metus, bibendum sed, posuere ac, mattis non, nunc. Vestibulum fringilla pede sit amet augue. In turpis. Pellentesque posuere. Praesent turpis. Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Nullam sagittis. Suspendisse pulvinar, augue ac venenatis condimentum, sem libero volutpat nibh, nec pellentesque velit pede quis nunc. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce id purus. Ut varius tincidunt libero. Phasellus dolor. Maecenas vestibulum mollis diam. Pellentesque ut neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. In dui magna, posuere eget, vestibulum et, tempor auctor, justo. In ac felis quis tortor malesuada pretium. Pellentesque auctor neque nec urna. Proin sapien ipsum, porta a, auctor quis, euismod ut, mi. Aenean viverra rhoncus pede. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Ut non enim eleifend felis pretium feugiat. Vivamus quis mi. Phasellus a est. Phasellus magna. In hac habitasse platea dictumst. Curabitur at lacus ac velit ornare lobortis. Curabitur a felis in nunc fringilla tristique.</p>
</div>
</div>
</div>
{% endblock content %}

We are just going to add a lot of lorem ipsum to give it some text for now. It is set up like the other files where we extend the base.html and add content within the content block.

Now that we have the HTML files set up, we can add the URL patterns to finish setting up these pages. We are going to keep these URLs in our fooddelivery/urls.py. We will add customer or restaurant specific urls in their respective apps but for these website views we will leave them in the root urls file:

from django.contrib import admin
from django.urls import path, include
from customer.views import Index, About
urlpatterns = [
path('admin/', admin.site.urls),
path('', Index.as_view(), name='index'),
path('about/', About.as_view(), name='about'),
]

We import the urls, add a pattern for each page, and use the class based view with as_view() which is required for class based views. Finally we give it a name which will need to match the names given in our navigation.html file.

This is where we are going to stop today, we have a basic web app set up that we can begin to add more features to in the future.

--

--