2 votes

Indiquez les heures d'ouverture exactes de l'entreprise

J'essaie de créer un champ personnalisé pour un modèle Django. J'ai besoin de stocker les heures d'ouverture pour chaque jour de la semaine.

class Restaurant(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
city = models.CharField(max_length=15)
street = models.CharField(max_length=15)
house_number = models.CharField(max_length=3)
flat_number = models.CharField(max_length=3, default='0')
phone_number = models.CharField(max_length=12)
image = models.ImageField()
rating = models.FloatField(validators=[validate_rating_number])

def __str__(self):
    return f'{self.name}, {self.city}'

Je dois enregistrer les heures d'ouverture dans un champ du type

opening_hours = models.CustomField()

2voto

Jacinator Points 892

Si vous ne voulez pas d'une table séparée et que vous utilisez une base de données postgreSQL, vous pouvez combiner la fonction TimeField avec un Champ de tableau . Cela ressemblerait à quelque chose comme ceci.

from django.contrib.postgres.fields import ArrayField
from django.db import models

class Restaurant(models.Model):
    opening_hours = ArrayField(models.TimeField(), size=7)

Vous pouvez alors accéder aux heures pour n'importe quel jour de la semaine en utilisant un index. En supposant que le dimanche est le premier jour de la semaine, vous pouvez accéder aux heures d'ouverture du mardi avec

restaurant.opening_hours[2]  # Sunday = 0, Monday = 1

Pour développer cette idée, vous pourriez ajouter les index avec des noms au modèle de restaurant afin qu'il soit encore plus évident dans votre code de savoir exactement ce que vous obtenez.

from django.contrib.postgres.fields import ArrayField
from django.db import models

class Restaurant(models.Model):
    SUN, MON, TUE, WED, THU, FRI, SAT = 0, 1, 2, 3, 4, 5, 6

    opening_hours = ArrayField(models.TimeField(), size=7)

r = Restaurant.objects.first()
r.opening_hours[r.TUE]

2voto

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X