mirror of
https://github.com/rjNemo/villafleurie
synced 2026-06-12 13:26:47 +00:00
minor advance in booking system
This commit is contained in:
parent
c412e2abdc
commit
527e7fd973
7 changed files with 291 additions and 143 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -8,4 +8,5 @@ rental/static/
|
||||||
.vscode/
|
.vscode/
|
||||||
Procfile
|
Procfile
|
||||||
heroku.yml
|
heroku.yml
|
||||||
|
rental/client_secrets.json
|
||||||
|
|
||||||
|
|
|
||||||
1
calendar.dat
Normal file
1
calendar.dat
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{"access_token": "ya29.Il-0B4bh7Yq32B8mvoTT0EiAbYtzr1snXN_AwfcJzzaXu_L74OpPkkH7UgxQIzh3ZkiF_7fQq5VwZ5lIPE8ag5iei_D58rDeFdvT6x3V0MC9uOAyTBsejAlh2aJl9hY1Lg", "client_id": "1068382961407-1dudhnc4e9d7ham53nr6b7ak3c4dlvme.apps.googleusercontent.com", "client_secret": "F9zmMyRRiTUEAMfRiv8A2l1d", "refresh_token": "1//09MUSHKoeusLDCgYIARAAGAkSNwF-L9IrNOqe0TCFB9n1MZZwuAQNtfkdXAv7x4bUs2AxMwfmTdccxSMhCMEwjaXRUD2WR_EXiss", "token_expiry": "2019-12-06T16:13:57Z", "token_uri": "https://accounts.google.com/o/oauth2/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "ya29.Il-0B4bh7Yq32B8mvoTT0EiAbYtzr1snXN_AwfcJzzaXu_L74OpPkkH7UgxQIzh3ZkiF_7fQq5VwZ5lIPE8ag5iei_D58rDeFdvT6x3V0MC9uOAyTBsejAlh2aJl9hY1Lg", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/calendar.readonly", "token_type": "Bearer"}, "scopes": ["https://www.googleapis.com/auth/calendar.readonly"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": false, "_class": "OAuth2Credentials", "_module": "oauth2client.client"}
|
||||||
138
rental/bookings.py
Normal file
138
rental/bookings.py
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
from googleapiclient import sample_tools
|
||||||
|
from google.auth.transport.requests import Request
|
||||||
|
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||||
|
from googleapiclient.discovery import build
|
||||||
|
import os.path
|
||||||
|
import pickle
|
||||||
|
import datetime
|
||||||
|
from oauth2client import client
|
||||||
|
import sys
|
||||||
|
# from rental.models import Reservation
|
||||||
|
|
||||||
|
|
||||||
|
def get_bookings(place):
|
||||||
|
"""
|
||||||
|
returns a list of all related place reservations
|
||||||
|
"""
|
||||||
|
booked_dates = Reservation.objects.all()
|
||||||
|
return [booking for booking in booked_dates if booking.place.name == f"{place.name}"]
|
||||||
|
|
||||||
|
|
||||||
|
def check_availability(place, start_date, end_date):
|
||||||
|
"""
|
||||||
|
check if the related place is available during a given period
|
||||||
|
"""
|
||||||
|
bookings = get_bookings(place)
|
||||||
|
for booking in bookings:
|
||||||
|
if (booking.start <= start_date <= booking.end) or (booking.start <= end_date <= booking.end):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
"""Simple command-line sample for the Calendar API.
|
||||||
|
Command-line application that retrieves the list of the user's calendars."""
|
||||||
|
|
||||||
|
|
||||||
|
def main1(argv):
|
||||||
|
# Authenticate and construct service.
|
||||||
|
service, _ = sample_tools.init(
|
||||||
|
argv, 'calendar', 'v3', __doc__, __file__,
|
||||||
|
scope='https://www.googleapis.com/auth/calendar.readonly')
|
||||||
|
|
||||||
|
try:
|
||||||
|
page_token = None
|
||||||
|
while True:
|
||||||
|
calendar_list = service.calendarList().list(
|
||||||
|
pageToken=page_token).execute()
|
||||||
|
for calendar_list_entry in calendar_list['items']:
|
||||||
|
print(calendar_list_entry['summary'])
|
||||||
|
page_token = calendar_list.get('nextPageToken')
|
||||||
|
|
||||||
|
if not page_token:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Call the Calendar API
|
||||||
|
calendar_list = service.calendarList().list(
|
||||||
|
pageToken=page_token).execute()
|
||||||
|
# print(calendar_list)
|
||||||
|
now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
|
||||||
|
print('Getting the upcoming 10 T2 arrivals')
|
||||||
|
|
||||||
|
events_result = service.events().list(calendarId='burik7aclvhc7vsboh06c179uo@group.calendar.google.com', timeMin=now,
|
||||||
|
maxResults=10, singleEvents=True,
|
||||||
|
orderBy='startTime').execute()
|
||||||
|
events = events_result.get('items', [])
|
||||||
|
|
||||||
|
if not events:
|
||||||
|
print('No upcoming events found.')
|
||||||
|
for event in events:
|
||||||
|
start = event['start'].get('dateTime', event['start'].get('date'))
|
||||||
|
end = event['end'].get('dateTime', event['end'].get('date'))
|
||||||
|
print(start, end, event['summary'])
|
||||||
|
|
||||||
|
print('Getting the upcoming 10 T3 arrivals')
|
||||||
|
events_result = service.events().list(calendarId='fu7h30p0gk4a2p4nvo7nsbgpok@group.calendar.google.com', timeMin=now,
|
||||||
|
maxResults=10, singleEvents=True,
|
||||||
|
orderBy='startTime').execute()
|
||||||
|
events = events_result.get('items', [])
|
||||||
|
|
||||||
|
if not events:
|
||||||
|
print('No upcoming events found.')
|
||||||
|
for event in events:
|
||||||
|
start = event['start'].get('dateTime', event['start'].get('date'))
|
||||||
|
end = event['end'].get('dateTime', event['end'].get('date'))
|
||||||
|
print(start, end, event['summary'])
|
||||||
|
|
||||||
|
except client.AccessTokenRefreshError:
|
||||||
|
print('The credentials have been revoked or expired, please re-run'
|
||||||
|
'the application to re-authorize.')
|
||||||
|
|
||||||
|
|
||||||
|
# If modifying these scopes, delete the file token.pickle.
|
||||||
|
# SCOPES = ['https://www.googleapis.com/auth/calendar.readonly']
|
||||||
|
|
||||||
|
|
||||||
|
# def main():
|
||||||
|
# """Shows basic usage of the Google Calendar API.
|
||||||
|
# Prints the start and name of the next 10 events on the user's calendar.
|
||||||
|
# """
|
||||||
|
# creds = None
|
||||||
|
# # The file token.pickle stores the user's access and refresh tokens, and is
|
||||||
|
# # created automatically when the authorization flow completes for the first
|
||||||
|
# # time.
|
||||||
|
# if os.path.exists('token.pickle'):
|
||||||
|
# with open('token.pickle', 'rb') as token:
|
||||||
|
# creds = pickle.load(token)
|
||||||
|
# # If there are no (valid) credentials available, let the user log in.
|
||||||
|
# if not creds or not creds.valid:
|
||||||
|
# if creds and creds.expired and creds.refresh_token:
|
||||||
|
# creds.refresh(Request())
|
||||||
|
# else:
|
||||||
|
# flow = InstalledAppFlow.from_client_secrets_file(
|
||||||
|
# 'credentials.json', SCOPES)
|
||||||
|
# creds = flow.run_local_server(port=0)
|
||||||
|
# # Save the credentials for the next run
|
||||||
|
# with open('token.pickle', 'wb') as token:
|
||||||
|
# pickle.dump(creds, token)
|
||||||
|
|
||||||
|
# service = build('calendar', 'v3', credentials=creds)
|
||||||
|
|
||||||
|
# # Call the Calendar API
|
||||||
|
# now = datetime.datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time
|
||||||
|
# print('Getting the upcoming 10 events')
|
||||||
|
# events_result = service.events().list(calendarId='primary', timeMin=now,
|
||||||
|
# maxResults=10, singleEvents=True,
|
||||||
|
# orderBy='startTime').execute()
|
||||||
|
# events = events_result.get('items', [])
|
||||||
|
|
||||||
|
# if not events:
|
||||||
|
# print('No upcoming events found.')
|
||||||
|
# for event in events:
|
||||||
|
# start = event['start'].get('dateTime', event['start'].get('date'))
|
||||||
|
# print(start, event['summary'])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main1(sys.argv)
|
||||||
|
# main()
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
from rental.models import Reservation
|
|
||||||
|
|
||||||
def get_bookings(place):
|
|
||||||
"""
|
|
||||||
returns a list of all related place reservations
|
|
||||||
"""
|
|
||||||
booked_dates = Reservation.objects.all()
|
|
||||||
return [booking for booking in booked_dates if booking.place.name == f"{place.name}"]
|
|
||||||
|
|
||||||
|
|
||||||
def check_availability(place, start_date, end_date):
|
|
||||||
"""
|
|
||||||
check if the related place is available during a given period
|
|
||||||
"""
|
|
||||||
bookings = get_bookings(place)
|
|
||||||
for booking in bookings:
|
|
||||||
if (booking.start <= start_date <= booking.end) or (booking.start <= end_date <= booking.end):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
@ -28,6 +28,7 @@ class Place(models.Model):
|
||||||
thumbnail = models.ForeignKey(
|
thumbnail = models.ForeignKey(
|
||||||
Image, on_delete=models.CASCADE, blank=True, null=True)
|
Image, on_delete=models.CASCADE, blank=True, null=True)
|
||||||
images = models.ManyToManyField(Image, related_name="places", blank=True)
|
images = models.ManyToManyField(Image, related_name="places", blank=True)
|
||||||
|
calendar = models.CharField(max_length=350, blank=True, null=True)
|
||||||
|
|
||||||
|
|
||||||
class Guest(models.Model):
|
class Guest(models.Model):
|
||||||
|
|
|
||||||
|
|
@ -1,154 +1,180 @@
|
||||||
{% extends 'rental/base.html'%}
|
{% extends 'rental/base.html'%} {% load static %} {% block content %}
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
{% block content %}
|
<section class="intro-single">
|
||||||
<!--/ Intro Single star /-->
|
<div class="container">
|
||||||
<section class="intro-single">
|
<div class="row">
|
||||||
<div class="container">
|
<div class="col-md-12 col-lg-8">
|
||||||
<div class="row">
|
<div class="title-single-box">
|
||||||
<div class="col-md-12 col-lg-8">
|
<h1 class="title-single">{{ place.subname }} {{ place.name }}</h1>
|
||||||
<div class="title-single-box">
|
<span class="color-text-a">VillaFleurie</span>
|
||||||
<h1 class="title-single">{{ place.subname }} {{ place.name }} </h1>
|
|
||||||
<span class="color-text-a">VillaFleurie</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12 col-lg-4">
|
|
||||||
<nav aria-label="breadcrumb" class="breadcrumb-box d-flex justify-content-lg-end">
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="{% url 'rental:index' %}">Accueil</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item">
|
|
||||||
<a href="{% url 'rental:list_place' %}">Hébergements</a>
|
|
||||||
</li>
|
|
||||||
<li class="breadcrumb-item active" aria-current="page">
|
|
||||||
{{ place.name }}
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-12 col-lg-4">
|
||||||
|
<nav
|
||||||
|
aria-label="breadcrumb"
|
||||||
|
class="breadcrumb-box d-flex justify-content-lg-end"
|
||||||
|
>
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'rental:index' %}">Accueil</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'rental:list_place' %}">Hébergements</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">
|
||||||
|
{{ place.name }}
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
<!--/ Intro Single End /-->
|
</section>
|
||||||
|
|
||||||
<!--/ Property Single Star /-->
|
<section class="property-single nav-arrow-b">
|
||||||
<section class="property-single nav-arrow-b">
|
<div class="container">
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<div class="row">
|
<div class="col-sm-12">
|
||||||
<div class="col-sm-12">
|
<div
|
||||||
<div id="property-single-carousel" class="owl-carousel owl-arrow gallery-property">
|
id="property-single-carousel"
|
||||||
{% for image in images %}
|
class="owl-carousel owl-arrow gallery-property"
|
||||||
<div class="carousel-item-b">
|
>
|
||||||
<img src="{{ image.img.url }}" alt="{{image.alt}}">
|
{% for image in images %}
|
||||||
</div>
|
<div class="carousel-item-b">
|
||||||
{% endfor %}
|
<img src="{{ image.img.url }}" alt="{{image.alt}}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="row justify-content-between">
|
{% endfor %}
|
||||||
<div class="col-md-5 col-lg-4">
|
</div>
|
||||||
<div class="property-price d-flex justify-content-center foo">
|
<div class="row justify-content-between">
|
||||||
<div class="card-header-c d-flex">
|
<div class="col-md-5 col-lg-4">
|
||||||
<div class="card-box-ico">
|
<div class="property-price d-flex justify-content-center foo">
|
||||||
<span class="ion-money">€</span>
|
<div class="card-header-c d-flex">
|
||||||
</div>
|
<div class="card-box-ico">
|
||||||
<div class="card-title-c align-self-center">
|
<span class="ion-money">€</span>
|
||||||
<h5 class="title-c"> {{ place.price }} </h5>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card-title-c align-self-center">
|
||||||
<div class="property-summary">
|
<h5 class="title-c">{{ place.price }}</h5>
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="col-md-12 mb-1">
|
|
||||||
<a href="#reservation"><button class="btn btn-a">Réserver maintenant</button></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="property-summary">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="title-box-d section-t4">
|
|
||||||
<h3 class="title-d">Résumé</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="summary-list">
|
|
||||||
<ul class="list">
|
|
||||||
<li class="d-flex justify-content-between">
|
|
||||||
<strong>Localisation :</strong>
|
|
||||||
<span>Le Gosier, Guadeloupe</span>
|
|
||||||
</li>
|
|
||||||
<li class="d-flex justify-content-between">
|
|
||||||
<strong>Status :</strong>
|
|
||||||
<span>Disponible</span>
|
|
||||||
</li>
|
|
||||||
<li class="d-flex justify-content-between">
|
|
||||||
<strong>Surface :</strong>
|
|
||||||
<span>{{ place.surface}}
|
|
||||||
<sup>2</sup>
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
<li class="d-flex justify-content-between">
|
|
||||||
<strong>Lits :</strong>
|
|
||||||
<span>{{ place.beds }}</span>
|
|
||||||
</li>
|
|
||||||
<li class="d-flex justify-content-between">
|
|
||||||
<strong>Nombre de voyageurs maximum :</strong>
|
|
||||||
<span>{{ place.max_occupation}}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-7 col-lg-7 section-md-t3">
|
<div class="col-sm-12">
|
||||||
|
<div class="title-box-d section-t4">
|
||||||
|
<a href="#reservation" class="btn btn-a">Réserver</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="property-summary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<div class="title-box-d">
|
<div class="title-box-d section-t4">
|
||||||
<h3 class="title-d">Description</h3>
|
<h3 class="title-d">Résumé</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="property-description">
|
<div class="summary-list">
|
||||||
<p class="description color-text-a">
|
<ul class="list">
|
||||||
{{ place.description |safe}}
|
<li class="d-flex justify-content-between">
|
||||||
</p>
|
<strong>Localisation :</strong>
|
||||||
<p class="description color-text-a no-margin">
|
<span>Le Gosier, Guadeloupe</span>
|
||||||
{{ place.info |safe}}
|
</li>
|
||||||
</p>
|
<li class="d-flex justify-content-between">
|
||||||
|
<strong>Status :</strong>
|
||||||
|
<span>Disponible</span>
|
||||||
|
</li>
|
||||||
|
<li class="d-flex justify-content-between">
|
||||||
|
<strong>Surface :</strong>
|
||||||
|
<span
|
||||||
|
>{{ place.surface}}
|
||||||
|
<sup>2</sup>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
<li class="d-flex justify-content-between">
|
||||||
|
<strong>Lits :</strong>
|
||||||
|
<span>{{ place.beds }}</span>
|
||||||
|
</li>
|
||||||
|
<li class="d-flex justify-content-between">
|
||||||
|
<strong>Nombre de voyageurs maximum :</strong>
|
||||||
|
<span>{{ place.max_occupation}}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<iframe
|
||||||
|
src="{{place.calendar | safe}}"
|
||||||
|
style="border-width:0"
|
||||||
|
width="400"
|
||||||
|
height="400"
|
||||||
|
frameborder="0"
|
||||||
|
scrolling="no"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-7 col-lg-7 section-md-t3">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="title-box-d">
|
||||||
|
<h3 class="title-d">Description</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="property-description">
|
||||||
|
<p class="description color-text-a">
|
||||||
|
{{ place.description |safe}}
|
||||||
|
</p>
|
||||||
|
<p class="description color-text-a no-margin">
|
||||||
|
{{ place.info |safe}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-10 offset-md-1">
|
</div>
|
||||||
<ul class="nav nav-pills-a nav-pills mb-3 section-t3" id="pills-tab" role="tablist">
|
<div class="col-md-10 offset-md-1">
|
||||||
<!-- <li class="nav-item">
|
<ul
|
||||||
|
class="nav nav-pills-a nav-pills mb-3 section-t3"
|
||||||
|
id="pills-tab"
|
||||||
|
role="tablist"
|
||||||
|
>
|
||||||
|
<!-- <li class="nav-item">
|
||||||
<a class="nav-link active" id="pills-video-tab" data-toggle="pill" href="#pills-video" role="tab"
|
<a class="nav-link active" id="pills-video-tab" data-toggle="pill" href="#pills-video" role="tab"
|
||||||
aria-controls="pills-video" aria-selected="true">Video</a>
|
aria-controls="pills-video" aria-selected="true">Video</a>
|
||||||
</li> -->
|
</li> -->
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" id="pills-map-tab" data-toggle="pill" href="#pills-map" role="tab" aria-controls="pills-map"
|
<a
|
||||||
aria-selected="false">Localisation</a>
|
class="nav-link active"
|
||||||
</li>
|
id="pills-map-tab"
|
||||||
</ul>
|
data-toggle="pill"
|
||||||
<div class="tab-content" id="pills-tabContent">
|
href="#pills-map"
|
||||||
<!-- <div class="tab-pane fade show active" id="pills-video" role="tabpanel" aria-labelledby="pills-video-tab">
|
role="tab"
|
||||||
|
aria-controls="pills-map"
|
||||||
|
aria-selected="false"
|
||||||
|
>Localisation</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content" id="pills-tabContent">
|
||||||
|
<!-- <div class="tab-pane fade show active" id="pills-video" role="tabpanel" aria-labelledby="pills-video-tab">
|
||||||
<iframe src="https://player.vimeo.com/video/73221098" width="100%" height="460" frameborder="0"
|
<iframe src="https://player.vimeo.com/video/73221098" width="100%" height="460" frameborder="0"
|
||||||
webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="tab-pane fade show active" id="pills-map" role="tabpanel" aria-labelledby="pills-map-tab">
|
<div
|
||||||
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3831.2547874074585!2d-61.48954768556058!3d16.207335988795712!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8c134f148764f5d5%3A0x981bb218cee8b16c!2sVillaFleurie!5e0!3m2!1sfr!2sde!4v1573125589212!5m2!1sfr!2sde"
|
class="tab-pane fade show active"
|
||||||
width="100%" height="460" frameborder="0" style="border:0;" allowfullscreen=""></iframe>
|
id="pills-map"
|
||||||
</div>
|
role="tabpanel"
|
||||||
|
aria-labelledby="pills-map-tab"
|
||||||
|
>
|
||||||
|
<iframe
|
||||||
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3831.2547874074585!2d-61.48954768556058!3d16.207335988795712!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x8c134f148764f5d5%3A0x981bb218cee8b16c!2sVillaFleurie!5e0!3m2!1sfr!2sde!4v1573125589212!5m2!1sfr!2sde"
|
||||||
|
width="100%"
|
||||||
|
height="460"
|
||||||
|
frameborder="0"
|
||||||
|
style="border:0;"
|
||||||
|
allowfullscreen=""
|
||||||
|
></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% include 'rental/reservation_form.html' %}
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% include 'rental/reservation_form.html' %}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
<!--/ Property Single End /-->
|
</section>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from django.views.generic.base import TemplateView
|
||||||
from .forms import ReservationForm
|
from .forms import ReservationForm
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from rental.pricing import get_reservation_price
|
from rental.pricing import get_reservation_price
|
||||||
from rental.calendar import check_availability
|
from rental.bookings import check_availability
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue