class LocationPage(Page): """ Detail for a specific bakery location. """ introduction = models.TextField(help_text="Text to describe the page", blank=True) image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", help_text="Landscape mode only; horizontal width between 1000px and 3000px.", ) body = StreamField( BaseStreamBlock(), verbose_name="Page body", blank=True, use_json_field=True ) address = models.TextField() lat_long = models.CharField( max_length=36, help_text="Comma separated lat/long. (Ex. 64.144367, -21.939182) " "Right click Google Maps and select 'What's Here'", validators=[ RegexValidator( regex=r"^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$", message="Lat Long must be a comma-separated numeric lat and long", code="invalid_lat_long", ), ], )
Locations have related operating hours through the LocationOperatingHours model:
bakerydemo/locations/models.py
class LocationOperatingHours(Orderable, OperatingHours): """ A model creating a relationship between the OperatingHours and Location """ location = ParentalKey( "LocationPage", related_name="hours_of_operation", on_delete=models.CASCADE )
The base OperatingHours abstract model defines:
class OperatingHours(models.Model): day = models.CharField(max_length=3, choices=DAY_CHOICES, default="MON") opening_time = models.TimeField(blank=True, null=True) closing_time = models.TimeField(blank=True, null=True) closed = models.BooleanField( "Closed?", blank=True, help_text="Tick if location is closed on this day" ) class Meta: abstract = True
class LocationsIndexPage(Page): """ A Page model that creates an index page (a listview) """ introduction = models.TextField(help_text="Text to describe the page", blank=True) image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+", help_text="Landscape mode only; horizontal width between 1000px and 3000px.", )
The lat_long field includes custom validation using RegexValidator:
validators=[ RegexValidator( regex=r"^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$", message="Lat Long must be a comma-separated numeric lat and long", code="invalid_lat_long", ),]
Valid formats:
64.144367, -21.939182
51.5074, -0.1278
-33.8688, 151.2093
Invalid formats will show an error message in the admin.