To develop a website with Django framework, a basic knowledge of python is important since django is a web development framework written in python. In this writeup we want to develop and Hotel management system or website with the django, lets get on it.
The first process is we design the project structure from the **ERD(entity-relational-diagram)** this diagram helps us to know what tables will be created and the relationship between them. we would use this information to structure all our models.py contents.
**the Link to the ERD is a stated bellow** `https://www.educative.io/shoteditor/5616024734400512`
Requirements: Python 3, django 2, django-environ, Pillow, django-shortcuts,psycopg2, django-heroku and gunicorn
*Steps:**
1. **On your terminal, cd to your favourite file location, say documents or desktop**
>> cd desktop or cd documents
>> mkdir Hotel-project
>> cd Hotel-project
The above lines of code: Takes you to your file location, say desktop. Create a folder-name with mkdir-command and enters the folder with the cd-command
2. **Now, in your Hotel-project folder, create a `virtual environment` such that all the needed libraries in this project can be installed into the environment**
>> python3 -m venv venv
>> source venv/bin/activate
>> pip install django, pip install django-environ……e.t.c
#Each library is installed individually
>> pip freeze -m requirements.txt
3. **Here, create your django project and and also all the needed apps**
# Still in the Hotel-project folder
>> django-admin startproject hotelsystem
## This creates the django project called hotelsystem where all other apps can be installed in
>> cd hotelsystem
>> python3 manage.py startapp authentication
>> python3 manage.py startapp booking
>> python3 manage.py startapp customer
>> python3 manage.py startapp receptionist
>> python3 manage.py startapp payment
the above processes get all our apps ready all in the exact file directory
>> django-project
>>> venv
>>> hotelsystem
>>>> authentication
>>>> booking
>>>> customer
>>>> hotelsystem
>>>> payment
>>>> receptionist
>>>> manage.py
>>>> requirements.txt
4. The CI/CD continous integration(github-action and continous deployment(to Heroku) of this Project
a. **Continous integration with github action** this was done by creating a `.github` folder, in this folder another folder called `workflow` was created. a file named `ci.yml` was created in the workflow folder. the content of the ci.yml was written as below
name: Django Testson: [push, pull_request]jobs:
build:
runs-on: ubuntu-lateststeps:
— uses: actions/checkout@v1
— name: setup python 3.9
uses: actions/setup-python@v1
with:
python_version: 3.9
— name: install dependencies
run: |
python -m pip install — upgrade pip
pip install -r requirements.txt
— name: Run migrations
run: hotelproject/Hotel-system/hotelsystem/manage.py migrate run: python hotelsystem/manage.py migrate
— name: Run tests
run: python3 hotelsystem/manage.py test# Added snippets
— name: Run Tests
run: |
python manage.py test
— name: Deploy to Heroku
env:
HEROKU_API_TOKEN: ${{ secrets.HEROKU_API_TOKEN }}
HEROKU_APP_NAME: ${{ secrets.HEROKU_APP_NAME }}
if: github.ref == ‘refs/heads/main’ && job.status == ‘success’
run: |
git remote add heroku https://heroku:$HEROKU_API_TOKEN@git.heroku.com/$HEROKU_APP_NAME.git
git push heroku HEAD:main -f
Then, we `git add, git commit and git push` to the active repository `. in the git-hub our git-action is set up with the ci.yml file automatically. we then go back to our editor and then `git pull`to get the newly updated files. now, we can now `git checkout` to a new branch and continue the development.
N.B: You branch out at intervals, work in that branch and then push to the branch when done. get to your git-hub again, merge the changes to the main after the push has been tested and found to pass all tests, get back to your editor, checkout to main again.
`Repeat this cycle at intervals of the different stages of the project development`
b. **Continous deployment to heroku:**
Website-name on heroku is `https://www.pyhotels.herokuapp.com`
A procfile file was created, in this file we add `web: gunicorn hotelsystem.wsgi — reload`, we also install guinicorn coupled with the django-heroku already install. once all is set we `git add . , git commit, git push to heroku`.(although there are few more steps to take..take the steps in the link below to get the deployment done:
‘https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Deployment'
Now, our project is life
5. Locate the inner hotelsystem and then, go-to settings: a. you add all the apps created in the INSTALLED_APPS list b. add your template directory in the TEMPLATES section c. add your desired database to DATABASES section. Note that all the data needed to be kept secret are saved in the `.env file` which should be created in the project directory d. timezone is set to your preferred location e. you add static_root, media_root so as for django to locate easily, the path of static and media files
5. You go to authentication app and set it up: In the Models.py file of Authentication
from django.db import models
from authentication.models import Customer,RoomManager
from datetime import dateclass Contact(models.Model):
name=models.CharField(max_length=100)
email=models.CharField(max_length=100)
message=models.TextField(max_length=2000)
def __str__(self):
return self.nameclass Rooms(models.Model):
manager=models.ForeignKey(RoomManager, on_delete=models.CASCADE)
room_no=models.CharField(max_length=5, )
room_type=models.CharField(max_length=50)
is_available=models.BooleanField(default=True)
price=models.FloatField(default=1000.00)
no_of_days_advance=models.IntegerField()
start_date=models.DateField(auto_now=False, auto_now_add=False)
room_image=models.ImageField(upload_to=”media”,
height_field=None, width_field=None,
max_length=None,default=’0.jpeg’)def __str__(self):
return “Room No: “+str(self.id)class Booking(models.Model):
room_no=models.ForeignKey(Rooms, on_delete=models.CASCADE)
user_id=models.ForeignKey(Customer, on_delete=models.CASCADE)
start_day=models.DateField(auto_now=False, auto_now_add=False)
end_day=models.DateField(auto_now=False, auto_now_add=False)
amount=models.FloatField()
booked_on=models.DateTimeField(auto_now=True, auto_now_add=False)def __str__(self):
return “Booking ID: “+str(self.id)
@property
def is_past_due(self):
return date.today()>self.end_day
In the terminal run the following commands to initiate and create the needed table in the database
In the `views.py file of the Authentication file you’d write
from django.shortcuts import render,redirect
from .models import Contact
from .models import Rooms,Booking
from authentication.models import Customer
from django.contrib import messages
from django.http import HttpResponse
import datetimedef index(request):
return render(request,’booking/index.html’,{})
def contact(request):
if request.method==”GET”:
return render(request,”contact/contact.html”,{})
else:
username=request.POST[‘name’]
email=request.POST[‘email’]
message=request.POST[‘message’]
data=Contact(name=username,email=email,message=message)
data.save()
return render(request,”contact/contact.html”,{‘message’:’Thank
you for contacting us.’})def book(request):
if request.method==”POST”:
start_date=request.POST[‘start_date’]
end_date=request.POST[‘end_date’]
request.session[‘start_date’]=start_date
request.session[‘end_date’]=end_date
start_date=datetime.datetime.strptime(start_date,
“%d/%b/%Y”).date()
end_date=datetime.datetime.strptime(end_date,
“%d/%b/%Y”).date()
no_of_days=(end_date-start_date).days
data=Rooms.objects.filter(is_available=True,
no_of_days_advance__gte=
no_of_days,start_date__lte=start_date)
request.session[‘no_of_days’]=no_of_days
return render(request,’booking/book.html’,{‘data’:data})
else:
return redirect(‘index’)def book_now(request,id):
if request.session.get(“username”,None) and
request.session.get(“type”,None)==’customer’:
if request.session.get(“no_of_days”,1):
no_of_days=request.session[‘no_of_days’]
start_date=request.session[‘start_date’]
end_date=request.session[‘end_date’]
request.session[‘room_no’]=id
data=Rooms.objects.get(room_no=id)
bill=data.price*int(no_of_days)
request.session[‘bill’]=bill
roomManager=data.manager.username
return render(request,”booking/book-now.html”,
{“no_of_days”:no_of_days,”room_no”:id,
“data”:data,”bill”:bill,”roomManager”:roomManager,
“start”:start_date,”end”:end_date})
else:
return redirect(“index”)
else:
next=”book-now/”+id
return redirect(‘user_login’)
def book_confirm(request):
room_no=request.session[‘room_no’]
start_date=request.session[‘start_date’]
end_date=request.session[‘end_date’]
username=request.session[‘username’]
user_id=Customer.objects.get(username=username)
room=Rooms.objects.get(room_no=room_no)
amount=request.session[‘bill’]
start_date=datetime.datetime.strptime(start_date,
“%d/%b/%Y”).date()
end_date=datetime.datetime.strptime(end_date, “%d/%b/%Y”).date()data=Booking(room_no=room,start_day=start_date,
end_day=end_date,amount=amount,user_id=user_id)
data.save()
room.is_available=False
room.save()
del request.session[‘start_date’]
del request.session[‘end_date’]
del request.session[‘bill’]
del request.session[‘room_no’]
messages.info(request,”Room has been successfully booked”)
return redirect(‘user_dashboard’)def cancel_room(request,id):
data=Booking.objects.get(id=id)
room=data.room_no
room.is_available=True
room.save()
data.delete()
return HttpResponse(“Booking Cancelled Successfully”)def delete_room(request,id):
data=Rooms.objects.get(id=id)
manager=data.manager.username
if manager==request.session[‘username’]:
data.delete()
return HttpResponse(“You have deleted the room successfully”)
else:
return HttpResponse(“Invalid Request”)
Then, you go-to the urls.py of the Authentication app, add the lines of code as below
from django.urls import path
from . import viewsurlpatterns=[
path(‘’,views.index,name=’index’),
path(‘book’,views.book,name=’book’),
path(‘contact-us’,views.contact,name=’contact-us’),
path(‘book-now/<str:id>’,views.book_now,name=’book-now’),
path(‘cancel-room/<str:id>’,views.cancel_room,name=’cancel
room’),
path(‘delete-room/<str:id>’,views.delete_room,name=’delete-
room’),]
Also, you add the classes of the models.py to the admin.py add the following
from django.contrib import admin
from .models import Contact, Rooms, Bookingadmin.site.register(Contact)
admin.site.register(Rooms)
admin.site.register(Booking)
you locate the project-directory(hotelsystem) and include authentication.urls in the path.
`This is the MVT architecture for the authentication: the url from the hotelsystem project get matched with the url of the app. app url connects to the views, the views then send query sets to the databases and retrieve information which is expressed with templates . Authentication involves register, login and logout of customers and mangers and the permissions(activities they can perform)`
N.B In the templates directory we have 3 templates:login( user_login.html, manager_login.html, logout.html)
>> base
>>>base.html
>> login
>>> logout.html
>>> manager_login.html
>>> user_login.html
All the contents of the templates can be found on my github repository `(https://www.github.com/swallahfx/Hotel-system)`
Now to the Booking app to the models.py of the Booking app you add the following lines of code:
from django.db import models
from authentication.models import Customer,RoomManager
from datetime import dateclass Contact(models.Model):
name=models.CharField(max_length=100)
email=models.CharField(max_length=100)
message=models.TextField(max_length=2000)
def __str__(self):
return self.nameclass Rooms(models.Model):
manager=models.ForeignKey(RoomManager, on_delete=models.CASCADE)
room_no=models.CharField(max_length=5, )
room_type=models.CharField(max_length=50)
is_available=models.BooleanField(default=True)
price=models.FloatField(default=1000.00)
no_of_days_advance=models.IntegerField()
start_date=models.DateField(auto_now=False, auto_now_add=False)
room_image=models.ImageField(upload_to=”media”,
height_field=None, width_field=None,
max_length=None,default=’0.jpeg’)
def __str__(self):
return “Room No: “+str(self.id)class Booking(models.Model):
room_no=models.ForeignKey(Rooms, on_delete=models.CASCADE)
user_id=models.ForeignKey(Customer, on_delete=models.CASCADE)
start_day=models.DateField(auto_now=False, auto_now_add=False)
end_day=models.DateField(auto_now=False, auto_now_add=False)
amount=models.FloatField()
booked_on=models.DateTimeField(auto_now=True,
auto_now_add=False)
def __str__(self):
return “Booking ID: “+str(self.id)
@property
def is_past_due(self):
return date.today()>self.end_day
The Booking app model.py contains the above listed classes or models, we also run `django mm and django m` to help initiate and create the Booking database.
The views and urls are as follows, just as explained with the authentication app the same achitectural design
from django.shortcuts import render,redirect
from .models import Contact
from .models import Rooms,Booking
from authentication.models import Customer
from django.contrib import messages
from django.http import HttpResponse
import datetimedef index(request):
return render(request,’booking/index.html’,{})
def contact(request):
if request.method==”GET”:
return render(request,”contact/contact.html”,{})
else:
username=request.POST[‘name’]
email=request.POST[‘email’]
message=request.POST[‘message’]
data=Contact(name=username,email=email,message=message)
data.save()
return render(request,”contact/contact.html”,{‘message’:’Thank
you for contacting us.’})
def book(request):
if request.method==”POST”:
start_date=request.POST[‘start_date’]
end_date=request.POST[‘end_date’]
request.session[‘start_date’]=start_date
request.session[‘end_date’]=end_date
start_date=datetime.datetime.strptime(start_date,
“%d/%b/%Y”).date()
end_date=datetime.datetime.strptime(end_date,
“%d/%b/%Y”).date()
no_of_days=(end_date-start_date).days
data=Rooms.objects.filter(is_available=
True,no_of_days_advance__gte=
no_of_days,start_date__lte=start_date)
request.session[‘no_of_days’]=no_of_days
return render(request,’booking/book.html’,{‘data’:data})
else:
return redirect(‘index’)
def book_now(request,id):
if request.session.get(“username”,None)
and request.session.get(“type”,None)
==’customer’:
if request.session.get(“no_of_days”,1):
no_of_days=request.session[‘no_of_days’]
start_date=request.session[‘start_date’]
end_date=request.session[‘end_date’]
request.session[‘room_no’]=id
data=Rooms.objects.get(room_no=id)
bill=data.price*int(no_of_days)
request.session[‘bill’]=bill
roomManager=data.manager.usernamereturn render(request,”booking/book-now.html”,
{“no_of_days”:no_of_days,”room_no”:id,
“data”:data,”bill”:bill,”roomManager”:
roomManager,”start”:start_date,”end”:end_date})
else:
return redirect(“index”)
else:
next=”book-now/”+id
return redirect(‘user_login’)
def book_confirm(request):
room_no=request.session[‘room_no’]
start_date=request.session[‘start_date’]
end_date=request.session[‘end_date’]
username=request.session[‘username’]
user_id=Customer.objects.get(username=username)
room=Rooms.objects.get(room_no=room_no)
amount=request.session[‘bill’]
start_date=datetime.datetime.strptime(start_date,
“%d/%b/%Y”).date()
end_date=datetime.datetime.strptime
(end_date, “%d/%b/%Y”).date()
data=Booking(room_no=room,start_day=start_date,end_day=end_date,
amount=amount,user_id=user_id)
data.save()
room.is_available=False
room.save()
del request.session[‘start_date’]
del request.session[‘end_date’]
del request.session[‘bill’]
del request.session[‘room_no’]
messages.info(request,”Room has been successfully booked”)
return redirect(‘user_dashboard’)def cancel_room(request,id):
data=Booking.objects.get(id=id)
room=data.room_no
room.is_available=True
room.save()
data.delete()
return HttpResponse(“Booking Cancelled Successfully”)def delete_room(request,id):
data=Rooms.objects.get(id=id)
manager=data.manager.username
if manager==request.session[‘username’]:
data.delete()
return HttpResponse(“You have deleted the room successfully”)
else:
return HttpResponse(“Invalid Request”)
And the the contents of the urls.py of the Booking app is as stated below
from django.urls import path
from . import views
urlpatterns=[
path(‘’,views.index,name=’index’),
path(‘book’,views.book,name=’book’),
path(‘contact-us’,views.contact,name=’contact-us’),
path(‘book-now/<str:id>’,views.book_now,name=’book-now’),
path(‘cancel-room/<str:id>’,views.cancel_room,name=’cancel-
room’),
path(‘delete-room/<str:id>’,views.delete_room,name=’delete-
room’),
]
Now to the customer app. We only have views.py and urls.py that helps you to recognise a customer and all their activities are as stated below
#Views.pyfrom django.shortcuts import render,redirect
from authentication.models import Customer
from booking.models import Booking
import datetime
def dashboard(request):
if request.session.get(‘username’,None) and request.session.get(‘type’,None)==’manager’:
return redirect(‘manager_dashboard’)
if request.session.get(‘username’,None) and request.session.get(‘type’,None)==’customer’:
username=request.session[‘username’]
data=Customer.objects.get(username=username)
booking_data=Booking.objects.filter(user_id=data).order_by(‘-id’)
counts=booking_data.filter(end_day__lt=datetime.datetime.now()).count()
available=len(booking_data)-counts
return render(request,”user_dash/index.html”,{“data”:booking_data,”count”:counts,”available”:available})
else:
return redirect(“user_login”)
def details(request,id,booking_id):
if not request.session.get(‘username’,None):
return redirect(‘manager_login’)
if request.session.get(‘username’,None) and request.session.get(‘type’,None)==’customer’:
return redirect(‘user_dashboard’)
try:
booking_data=Booking.objects.get(id=booking_id)
user=Customer.objects.get(id=id)
return render(request,”user_dash/details.html”,{“user”:user,”booking_data”:booking_data})
except:
return redirect(“/manager/dashboard1/”)#urls.pyfrom django.urls import path
from . import views
urlpatterns=[
path(‘’,views.dashboard,name=’user_dashboard’),
path(‘details/<int:id>/<int:booking_id>’,views.details,
name=’user_details’)
]
Now to the receptionist app,
here we have the views.py where all the receptionist logic is and its urls.py that matched with the urls.py file of the project(hotelsystem) it is as stated below:
views.pyfrom django.shortcuts import render,redirect
from authentication.models import RoomManager
from booking.models import Booking,Rooms
from datetime import date
from django.contrib import messages
import datetimedef dashboard(request):
if not request.session.get(‘username’,None):
return redirect(‘manager_login’)
if request.session.get(‘username’,None) and request.session.get
(‘type’,None)==’customer’:
return redirect(‘user_dashboard’)
if request.session.get(‘username’,None) and request.session.get
(‘type’,None)==’manager’:
username=request.session[‘username’]
data=RoomManager.objects.get(username=username)
room_data=data.rooms_set.all()
booked=room_data.filter(is_available=False).count()
print(booked)
return render(request,”manager_dash/index.html”,
{“room_data”:room_data,”manager”:
data,”booked”:booked})
else:
return redirect(“manager_login”)
def add_room(request):
if not request.session.get(‘username’,None):
return redirect(‘manager_login’)
if request.session.get(‘username’,None) and request.session.get
(‘type’,None)==’customer’:
return redirect(‘user_dashboard’)
if request.method==”GET”:
return render(request,”manager_dash/add-room.html”,{})
else:
room_no=request.POST[‘room_no’]
room_type=request.POST[‘room_type’]
price=request.POST[‘price’]
room_image=request.FILES.get(‘room_image’,None)
no_of_days_advance=request.POST[‘no_of_days_advance’]
start_day=request.POST[‘start_day’]
error=[]
if(len(room_no)<1):
error.append(1)
messages.warning(request,”Room No Field must be
atleast 3 digit like 100.”)
if(len(room_type)<5):
error.append(1)
messages.warning(request,”Select a valid Room
Type.”)
if(len(price)<=2):
error.append(1)
messages.warning(request,”Please enter price”)
if(len(no_of_days_advance)<1):
error.append(1)
messages.warning(request,”Please add valid no of
days a user can book room in advance.”)
if(len(start_day)❤):
error.append(1)
messages.warning(request,”Please add the starting
day”)
if(not len(error)):
manager=request.session[‘username’]
manager=RoomManager.objects.get(username=manager)
room=Rooms(room_no=room_no,room_type=room_type
,price=price,no_of_days_advance=
no_of_days_advance,start_date
=datetime.datetime.strptimestart_day, “%d %B,
%Y”).date(),room_image=room_image,manager=manager)
room.save()
messages.info(request,”Room Added Successfully”)
return redirect(‘/manager/dashboard1/’)
else:
return redirect(‘/user/add-room/new/’)def update_room(request,room_no):
if not request.session.get(‘username’,None):
return redirect(‘manager_login’)
if request.session.get(‘username’,None) and request.session.get
(‘type’,None)==’customer’:
return redirect(‘user_dashboard’)
room=Rooms.objects.get(room_no=room_no)
if request.method==”GET”:
return render(request,”manager_dash/edit-room.html”,
{“room”:room})
else:
price=request.POST[‘price’]
no_of_days_advance=request.POST[‘no_of_days_advance’]
error=[]
if(len(price)<=2):
error.append(1)
messages.warning(request,”Please enter correct
price”)
if(len(no_of_days_advance)<1):
error.append(1)
messages.warning(request,”Please add valid no of
days a user can book room in advance.”)
if(not len(error)):
manager=request.session[‘username’]
manager=RoomManager.objects.get(username=manager)
room.price=price
room.no_of_days_advance=no_of_days_advance
room.save()
messages.info(request,”Room Data Updated
Successfully”)
return redirect(‘/manager/dashboard1/’)
else:
return redirect(‘/user/add-
room/update/’+room.room_no,{“room”:room})#The urls.py filefrom django.urls import path
from . import views
urlpatterns = [
path(‘’,views.dashboard,name=”manager_dashboard”),
path(‘new/’,views.add_room,name=”add_room”),
path(‘update/<int:room_no>/’,views.update_room,
name=”update_room”),
]
Now the payment app: here we use the paystack api, we also have various additional files like forms.py and paystack.py. in the settings.py field of the project we added the paystack authentication keys which was used to access the paystack api. although the key was protected with our django-environ
the files are as stated below
#forms.pyfrom django import forms
from .models import Paymentclass PaymentForm(forms.ModelForm):
class Meta:
model = Payment
fields = (‘amount’, ‘email’)
def __str__(self):
return self.model#models.pyfrom django.db import models
import secrets
from .paystack import PayStack## Create your models here.class Payment(models.Model):
amount = models.PositiveIntegerField()
ref = models.CharField(max_length= 200)
email = models.EmailField()
verified = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = (‘-date_created’,)
def __str__(self) -> str:
return f”Payment: {self.amount}”
def save(self, *args, **kwargs) -> None:
while not self.ref:
ref = secrets.token_urlsafe(50)
object_with_similar_ref =
Payment.objects.filter(ref=ref)
if not object_with_similar_ref:
self.ref = ref
super().save(*args, **kwargs)
def amount_value(self) -> int:
return self.amount * 100
def verify_payment(self):
paystack = PayStack()
status, result = paystack.verify_payment(self.ref,
self.amount)
if status:
if result[‘amount’] / 100 == self.amount:
self.verified = True
self.save()
if self.verified:
return True
return False
def __unicode__(self):
return self.name#Paystack.pyfrom django.conf import settings
import requestsclass PayStack:
PAYSTACK_SECRET_KEY = settings.PAYSTACK_SECRET_KEY
base_url = ‘https://api.paystack.co'
def verify_payment(self, ref, *args, **kwargs):
path = f’/transactions/verify/{ref}’
headers = {
“Authorization”: f”Bearer {self.PAYSTACK_SECRET_KEY}”,
‘Content-Type’: ‘application/json’,
}
url = self.base.url + path
response = requests.get(url, headers = headers)
if response.status_code == 200:
response_data = response.json()
return response_data[‘status’], response_data[‘data’]
response_data = response.json()
return response_data[‘status’], response_data[‘message’]## Views.pyfrom django.shortcuts import render
from django.http.request import HttpRequest
from django.http.response import HttpResponse
from django.shortcuts import get_object_or_404, redirect, render
from .import forms
from django.contrib import messages
from django.conf import settings
from .models import Payment## Create your views here.def initiate_payment(request: HttpRequest) -> HttpResponse:
if request.method == “POST”:
payment_form = forms.PaymentForm(request.POST)
if payment_form.is_valid():
payment = payment_form.save()
my_context = {‘payment’: payment,
‘paystack_public_key’:
settings.PAYSTACK_PUBLIC_KEY}
return render(request, ‘make_payment.html’, my_context)
else:
payment_form = forms.PaymentForm()
context2 = {‘payment_form’: payment_form}
return render(request,
‘payment/initiate_payment.html’, context2)def verify_payment(request: HttpRequest, ref: str) -> HttpResponse:
payment = get_object_or_404(Payment, ref=ref)
verified = payment.verify_payment()
if verified:
messages.success(request, “Verification Success”)
else:
messages.error(request, “Verification Failed.”)
return redirect(‘initiate-payment’)## Urls.pyfrom django.urls import path
from .import viewsurlpatterns = [
# path(‘’, views.initiate_payment, name=”initiate-payment”),
path(‘initiate-payment’, views.initiate_payment, name=”initiate-
payment”),
path(‘<str:ref>/’, views.verify_payment, name =”verify-
payment”),
]
N.B We used django-environ to secure all the important information or secret codes. To do this we create a `.env` file in the project directory where all the secret codes are saved and it should be added to another file called .gitignore a “gitignore file is a githubfile that keeps infomation of things that should be neglected whenever you push to or pull request from the github. other file to be added to the .gitignore is venv
Source: Medium - Adeniyi saheed
The Tech Platform
Utilizing a hotel channel manager developed by a specialized hotel software company can significantly improve the efficiency of managing hotel bookings and inventory. Their expertise in creating a hotel channel manager with Django ensures that your property can easily synchronize room availability and rates across multiple online distribution channels, ultimately maximizing bookings and revenue.