Vous pouvez définir votre propre champ personnalisé qui contiendra toutes les heures d'ouverture par jour. Ici, nous utiliserons un OpeningHours
classe qui contiendra l'heure d'ouverture par jour de type datetime.time ce qui signifie entrer une heure non valide, par exemple 12:61
échouerait à la validation. Ensuite, nous l'enregistrerons sous la forme d'une chaîne de caractères séparée par des espaces dans le champ de la base de données. opening_hours
par exemple
12:00 15:00 18:00 18:30 09:00 12:00 08:45
Il ne nous reste plus qu'à configurer :
- Sauvegarde du champ personnalisé dans la base de données à partir d'une instance de type
OpeningHours
à cette chaîne de caractères séparés par des espaces, plusieurs fois par jour, via get_prep_value()
- Récupération du champ personnalisé de la base de données à partir de cette chaîne de caractères séparée par des espaces vers une instance de
OpeningHours
via from_db_value()
models.py
from datetime import datetime
from django.core.exceptions import ValidationError
class OpeningHours:
FORMAT = '%H:%M'
def __init__(self, mon, tue, wed, thu, fri, sat, sun):
self.mon = datetime.strptime(mon, self.FORMAT).time()
self.tue = datetime.strptime(tue, self.FORMAT).time()
self.wed = datetime.strptime(wed, self.FORMAT).time()
self.thu = datetime.strptime(thu, self.FORMAT).time()
self.fri = datetime.strptime(fri, self.FORMAT).time()
self.sat = datetime.strptime(sat, self.FORMAT).time()
self.sun = datetime.strptime(sun, self.FORMAT).time()
def __str__(self):
return ' '.join(
dt_time.strftime(self.FORMAT)
for dt_time in (
self.mon,
self.tue,
self.wed,
self.thu,
self.fri,
self.sat,
self.sun,
)
)
class OpeningHoursField(models.CharField):
description = "Opening time per day"
def from_db_value(self, value, expression, connection):
return self.to_python(value)
def to_python(self, value):
if value is None or isinstance(value, OpeningHours):
return value
try:
obj = OpeningHours(*value.split())
except Exception:
raise ValidationError("Invalid opening time")
else:
return obj
def get_prep_value(self, value):
return str(value)
class Restaurant(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
city = models.CharField(max_length=15)
opening_hours = OpeningHoursField(max_length=100)
def __str__(self):
return f'{self.name}, {self.city}'
Créer un nouveau Restaurant
nécessiterait un OpeningHours
à définir comme l'objet personnalisé opening_hours
champ :
>>> from my_app.models import *
>>> opening_hours = OpeningHours(mon="12:00", tue="15:00", wed="18:00", thu="18:30", fri="09:00", sat="12:00", sun="08:45")
>>> obj = Restaurant.objects.create(name="Burger King", city="London", opening_hours=opening_hours)
>>> obj.save()
>>> obj.__dict__
{'_state': <django.db.models.base.ModelState object at 0x7fe3c5b4cb50>, 'id': 1, 'name': 'Burger King', 'city': 'London', 'opening_hours': <my_app.models.OpeningHours object at 0x7fe3c5b4c1f0>}
Lire le opening_hours
est tout comme la lecture d'une OpeningHours
objet :
>>> print(obj.opening_hours)
12:00 15:00 18:00 18:30 09:00 12:00 08:45
>>> obj.opening_hours.mon
datetime.time(12, 0)
>>> obj.opening_hours.tue
datetime.time(15, 0)
>>> obj.opening_hours.wed
datetime.time(18, 0)
>>> obj.opening_hours.thu
datetime.time(18, 30)
>>> obj.opening_hours.fri
datetime.time(9, 0)
>>> obj.opening_hours.sat
datetime.time(12, 0)
>>> obj.opening_hours.sun
datetime.time(8, 45)
Pour mettre à jour l'heure d'un jour particulier, il suffit de mettre à jour le champ correspondant et d'enregistrer.
>>> # Display old value
>>> print(Restaurant.objects.first().opening_hours)
12:00 15:00 18:00 18:30 09:00 12:00 08:45
>>> print(Restaurant.objects.first().opening_hours.thu)
18:30:00
>>>
>>> # Update new value for Thursday and save
>>> obj.opening_hours.thu = datetime.time(hour=1, minute=23)
>>> obj.save()
>>>
>>> # Display updated value
>>> print(Restaurant.objects.first().opening_hours)
12:00 15:00 18:00 01:23 09:00 12:00 08:45
>>> print(Restaurant.objects.first().opening_hours.thu)
01:23:00