We will build a simple Django-based hotel search app that lets users dynamically sort and filter hotels by price. Using Django for the backend and Vue.js for the frontend, we’ll create an interactive interface where users can instantly view hotels sorted in ascending or descending order and filter by maximum price, all without page reloads.
Setup Django Project and App
Prerequisites:
Create a new Django project and navigate into it:
django-admin startproject hotel_search
cd hotel_search
Create a Django app called home:
python manage.py startapp home
File Structure

Then we need to register app in settings.
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"home",
]
Define the Hotel Model
home/models.py: This code defines a Django model named 'Hotel' with fields for the hotel's name, price, description, and timestamps for creation and updates. The __str__ method returns the hotel's name for a human-readable representation.
from django.db import models
class GFG(models.Model):
hotel_name = models.CharField(max_length=100)
hotel_price = models.IntegerField()
hotel_description = models.TextField()
created_at = models.DateField(auto_now_add =True)
updated_at = models.DateField(auto_now =True)
def __str__(self) -> str:
return self.hotel_name
Create Views for Display and API
home/views.py: This code defines two view functions:
- home(request): This function renders the 'home.html' template when the home page is accessed.
- get_hotel(request): This function handles requests for hotel data. It retrieves hotel objects from the database, allows sorting by price (ascending or descending), and filters by price based on the 'amount' parameter in the GET request. It then converts the hotel information into JSON format and returns it as a JSON response.
- Comments have been added to explain each part of the code and its functionality.
from django.shortcuts import render
from .models import *
from django.http import JsonResponse
# Create your views here.
def home(request):
return render(request, 'home.html')
def get_hotel(request):
try:
Ans_objs = GFG.objects.all()
if request.GET.get('sort_by'):
sort_by_value = request.GET.get('sort_by')
if sort_by_value == 'asc':
Ans_objs = Ans_objs.order_by('hotel_price')
elif sort_by_value == 'dsc':
Ans_objs = Ans_objs.order_by('-hotel_price')
if request.GET.get('amount'):
amount = request.GET.get('amount')
Ans_objs = Ans_objs.filter(hotel_price__lte=amount)
payload = []
for Ans_obj in Ans_objs:
payload.append({
'name': Ans_obj.hotel_name,
'price': Ans_obj.hotel_price,
'description': Ans_obj.hotel_description,
})
return JsonResponse(payload, safe=False)
except Exception as e:
print(e)
return JsonResponse({'message': 'Something went wrong !'})
Admin Registration
home/admin.py: Then we register out app in admin.py file.
- It imports the necessary modules.
- It defines a custom admin class, HotelAdmin, to specify how the Hotel model is displayed in the admin interface. It chooses which fields to display in the list view.
- It registers the Hotel model with the custom admin class, connecting it to the admin interface so that you can manage hotel records easily.
from django.contrib import admin
from .models import *
# Register your models here.
class GFGAdmin(admin.ModelAdmin):
list_display = ['hotel_name', 'hotel_price',
'hotel_description']
admin.site.register(GFG, GFGAdmin)
Configure URLs
Project/urls.py: Then we map the project url with app url by adding include method for map the urls.py file of our app
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('home.urls')),
path("admin/", admin.site.urls),
]
App/urls.py: Then we write a connect all files by creating the urls in app's urls.py file.
from .views import *
from django.urls import path, include
urlpatterns = [
path('', home),
path('api/get_GFG/', get_hotel),
]
Templates Folder
In template folder we create the home.html file through which we create the representation of our project so let's start
- This is an HTML page that uses Vue.js for interactivity and Bootstrap for styling.
- It displays a list of hotels and provides controls for sorting and filtering hotels by price.
- The JavaScript code within the <script> tags initializes a Vue.js app (var app = new Vue) that fetches hotel data from an API based on sorting and price filtering.
- The data-binding syntax [[hotel.hotel_name]] and event listeners like @change="sortBy" are used to connect Vue.js to the HTML elements.
- The page loads Bootstrap CSS and JavaScript for styling and functionality.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap demo</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<style>
.text-center {
margin-top: -6%;
font-weight: bold;
color: green;
}
h4 {
color: red;
}
</style>
<body>
<div id="app" class="container mt-5 pt-5">
<h1 class="text-center">GeeksforGeeks </h1>
<h4>Search/Sort Hotel By Price :- </h4>
<br>
<div class="row">
<div class="col-md-4">
<label for=""><strong>Sort By</strong></label>
<select class="form-control" v-model="selectedSort" @change="sortBy">
<option value="asc">ASC</option>
<option value="dsc">DSC</option>
</select>
</div>
<div class="col-md-4">
<label for="customRange3" class="form-label"><strong>Select Price</strong></label>
<input type="range" class="form-range" @change="priceChange($event)" min="1000" max="10000" step="100"
id="customRange3">
</div>
</div>
<div class="row mt-5 pt-5">
<div class="col-md-4" v-for="hotel in hotels">
<div class="card shadow-lg" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">[[hotel.name]]</h5>
<p class="card-text">[[(hotel.description).substr(0, 30)]]</p>
<a href="#" class="btn btn-primary">Rs. [[hotel.price]]</a>
</div>
</div>
<br>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
data: {
message: 'Hello Django Hotel App!',
hotels: [],
selectedSort: 'asc', // Default sorting option
},
methods: {
getGFG(sort = '', amount = '') {
console.log(sort, amount);
fetch(`/api/get_GFG/?sort_by=${sort}&amount=${amount}`)
.then(response => response.json())
.then(result => {
console.log(result);
this.hotels = result;
});
},
sortBy(e) {
this.getGFG(sort = this.selectedSort);
},
priceChange(e) {
this.getGFG(' ', amount = e.target.value, ' ');
},
},
created() {
this.getGFG();
console.log("Page loaded");
}
});
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
</body>
</html>
Run Migrations and Create Superuser
Run the following commands to prepare your database:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
Use the Django admin panel at http://127.0.0.1:8000/admin/ to add hotel records.
Run Your Server and Test
Start your development server:
python manage.py runserver
Output
