With the Deployed version of this Web App:
- Vendors can Register their Restaurants to have an online presence and receive orders remotely.
- Vendors can manage their opening hours, menu, range of delivery etc.
- Buyers can search restaurants or food by their current location or for another location within a specific radius
- Buyers can generate single order from multiple restaurants and the rest will be taken care by the application
- Buyers can pay securely through PhonePe payment gateway with their preferrable payment method (e.g.- Card, Netbanking, UPI etc.)
- Location based Restaurant search using GDAL, GeoDjango & Google Maps API
- Live payment using PhonePe payment Gateway
- Single order generation from Multiple Restaurants
- Token Verification for authentication
- Refresh-less cart functionalities using AJAX
- Responsive UI to suit every device
- Clean, Maintainable & Scalable codebase
However it is not possible to list down all the tiny but complex functionalities this app can perform. So to have a glance of the working app, watch this video
- Usage
- Key Features
- Server Setup Guide
- Prerequisites
- Windows Setup
- Make a clone of this repo at your preferred location
- Create a Virtual Environment
- Activate the Virtual Evironment
- Install the required packages
- Set environment variables
- Install GDAL from the wheel provided
- Configure GDAL
- Create a Database
- Create necessary tables in the Database
- Install PostGIS
- Collect Static Files
- Good to go. Run the server
- Linux Setup
- Go to your User Directory
- Clone the repository
- Change working Directory to the newly cloned "Cyber_Restaurant" Directory in terminal
- Create a Virtual Environment
- Activate the Virtual Environment
- Install the required packages
- Set environment variables
- Install GDAL
- Install and Enable PostgreSQL
- Configure PostgreSQL
- Install PostGIS
- Collect Static Files
- Run the server on 8000 port
- Setup Gunicorn to serve the Django Application
- Setup NGINX as a Reverse Proxy to serve Static and Media Files
- Allow required ports
- Open Issues
- Want to Contribute?
- Found a BUG π ??
- Acknowledgements
As this is a pretty complex project and uses various different technologies, it is a quite long process to run the project locally or on a server. But the good news is, I have covered it all here and after following these steps you can deploy it or run it locally.
- Linux or Windows OS
- Python version 3.11.6 (Because as on 31/03/24 there is no GDAL release for higher python version)
- Git Installed
- Google Maps API Key with Geocoding, Maps Javascript and Places API enabled
git clone https://github.com/Bikram-Sankhari/Cyber_Restaurant.git
python -m venv env
env\Scripts\activate
pip install -r requirements.txt
- Create a copy of the '.env-sample' file in the root directory of the project and rename the copy to ".env"
- Some of the fields will be pre-filled, no need to change them. Fill out the rest
- 'DB_NAME' can be anything as your wish, but in the upcoming steps you will need to create a database with the same name
- 'GEMINI_API_KEY' is optional, if you don't have one then just remove the line
pip install GDAL-3.4.whl
-
Open 'settings.py' in 'Restaurant' sub-directory
-
Under the comment "GDAL Configuration" replace the IF block with the following code
pwd = os.getcwd() os.environ['PATH'] = os.path.join(pwd, 'env\Lib\site-packages\osgeo') + ';' + os.environ['PATH'] os.environ['PROJ_LIB'] = os.path.join(pwd, 'env\Lib\site-packages\osgeo\data\proj') + ';' + os.environ['PATH'] GDAL_LIBRARY_PATH = os.path.join(pwd, 'env\Lib\site-packages\osgeo\gdal304.dll') GEOS_LIBRARY_PATH = os.path.join(pwd, 'env\Lib\site-packages\osgeo\geos_c.dll')
9. Download and Install PostgreSQL from here
(Make sure you install PgAdmin and Application Stack Builder).
For a step by step guide watch this video
- Open "PGAdmin" and enter your password
- Expand the Servers menu
- Right Click on 'Databases' and create a new Database
- Database Name should be same as in your .env file and let the user be 'postgres' by default
python manage.py makemigrations
python manage.py migrate
-
Open "Application Stack Builder"
-
Select PostgreSQL and click 'Next'
-
It will show the list of available extensions. From here expand the 'Spatial Extensions' menu and check the latest version of PostGIS
-
Continue the installation as per prompt
-
After completition of the installation process, open "PGAdmin"
-
Expand the Database that you created
-
Click on the "Query Tool (π’)" at top
-
Write the following command to create the postgis extension on the database
CREATE EXTENSION postgis;
-
Click on the "Execute (βΆ)" button
python manage.py collectstatic
python manage.py runserver
For Linux Operating System, the installation is little more complex than windows, because it is similar to deploying the application on a remote server. The only difference is, for local machine you run the comands on your local terminal and for a remote server you run the commands on a secure shell connected and authenticated with the server.
-
Open Terminal by pressing CTRL + ALT + T
-
Change working directory to your user directory
cd ~
git clone https://github.com/Bikram-Sankhari/Cyber_Restaurant.git
cd Cyber_Restaurant/
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt
- Create a copy of the '.env-sample' file in the root directory of the project and rename the copy to ".env"
- Some of the fields will be pre-filled, if you have valid values for them then you can change them otherwise let them be as they are. Fill out the rest
- 'DB_NAME' can be anything as your wish, but in the upcoming steps you will need to create a database with the same name
- 'GEMINI_API_KEY' is optional, if you don't have one then just remove the line
-
As a prerequisite for installing GDAL, install python3-dev
sudo apt install python3-dev
-
Add GDAL release package to your apt repository
sudo add-apt-repository ppa:ubuntugis/ppa
-
Update system packages
sudo apt-get update && sudo apt-get upgrade -y
-
Install GDAL binary
sudo apt-get install gdal-bin
sudo apt-get install postgresql postgresql-contrib
sudo systemctl start postgresql.service
sudo systemctl enable postgresql.service
-
By default PostgrSQL creates a user named 'postgres'
-
Set a password for the 'postgres' user
sudo passwd postgres
-
Switch to 'postgres' user
sudo su - postgres
-
You may need to reset the password again. If you face any error in the next steps then run this command and follow the next steps again
[Replace 'NEW PASSWORD' with your desired password]psql -d postgres -c "ALTER USER postgres WITH PASSWORD 'NEW PASSWORD';"
-
Login to PostgreSQL Shell
psql postgres
-
Create a new Database.
[Replace 'db_name' with the name you entered in the .env file]CREATE DATABASE 'db_name';
-
Get back to the SUDO user terminal
exit exit
-
Create tables in the database
python3 manage.py makemigrations python3 manage.py migrate
-
Install 'ca-certificates' package to download and install certificates
sudo apt install ca-certificates
-
Install 'gnupg' package to dearmor ASCII files
sudo apt install gnupg
-
Add pgdg keys and main repo
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
-
Update system packages
sudo apt update && sudo apt upgrade -y
-
Check the version of PostgreSQL you are using
pg_config --version
-
Install PostGIS for your PostgreSQL version
[Replace <version> with the version of PostgreSQL you just checked]sudo apt install postgresql-<version>-postgis-3
-
Create PostGIS extension on your database
[Replace <database name> with the name of your database]sudo su postgres psql postgres \connect <database name> CREATE EXTENSION postgis; exit exit
python manage.py collectstatic
-
Install 'ufw' package to enable 8000 port
sudo apt install ufw
-
Enable 8000 port
sudo ufw allow 8000
-
Run the server
gunicorn --bind 127.0.0.1:8000 Restaurant.wsgi
-
Now if you reach out to this url you should see your server running, but there should be something wrong. The stylings and static files are not loading right? Don't worry we are going to fix them in the next steps.
-
Stop the server by pressing CTRL + C
-
Create a Gunicorn socket file
sudo nano /etc/systemd/system/gunicorn.socket
-
Enter the following configuration in the file and save
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target
-
Create a Gunicorn service file
sudo nano /etc/systemd/system/gunicorn.service
-
Enter the following configuration in the file and save
[Replace <username> with the name of your sudo user][Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=<username> Group=www-data WorkingDirectory=/home/<username>/Cyber_Restaurant ExecStart=/home/<username>/Cyber_Restaurant/env/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ Restaurant.wsgi:application [Install] WantedBy=multi-user.target
-
Restart Gunicorn
sudo systemctl restart gunicorn
-
Create a NGINX configuration file
sudo nano /etc/nginx/sites-available/Cyber_Restaurant
-
Enter the following code in the file and save
[Replace <username> with the name of your sudo user]
[Change the 'server_name' if you want to deploy the Application on a remote server]server { listen 80; server_name 127.0.0.1; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/<username>/Cyber_Restaurant; } location /media/ { root /home/<username>/Cyber_Restaurant; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock } }
-
Create a link to the configuration file
sudo ln -s /etc/nginx/sites-available/Cyber_Restaurant etc/nginx/sites-enabled/
-
Change the NGINX user
sudo nano /etc/nginx/nginx.conf
-
Set 'user' to your sudo username and save the file
-
Restart NGINX
sudo systemctl restart nginx
-
Allow the required ports
sudo ufw allow 586 sudo ufw allow 80 sudo ufw allow 'Nginx Full'
-
Remove 8000 port
sudo ufw delete allow 8000
Open 127.0.0.1 on your browser.
I have kept this issue open, to show How Location based search functionalities are working behind the scene to show relevant Restaurants nearby? How it is using GeoDjango with Google Maps API to fetch Restaurants inside a certain Radius? However this issue can be solved very easily.
I am planning to create a Celery Asynchronous job to intimate the Restaurant as well as the Customer whenever the Restaurant gets opened. And also there may be some scenarios when the Restaurant has actually not closed but due to some minute differences in Opening Hours Slabs, the system is showing the status Closed. In that case, we can ask the Restaurant owner whether to accept the order or not. So looking forward for some additional Features
All contributions are Welcome. If you want to contribute to this project follow the steps.
See GitHub Documentation for Forks
git clone <URL TO YOUR FORK>
git checkout -b <YOUR BRANCH NAME>
After making the changes, Test your code well before committing
See The GitHub Documentation on Pull Request
Be Descriptive about the Contribution you have made
As this Application is in the very early stage of it's development lifecycle, it is anticipated that there are some bugs in the code. So if you find out one, then Please - Let me know directly by Email: bikramsankhari2024@gmail.com
I would like to Thank Django Official Forum for helping me out on RUNTIME MODEL VALIDATION issue.