models.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. from django.core.validators import RegexValidator
  2. from django.db import models
  3. from modelcluster.fields import ParentalKey
  4. from wagtail.wagtailadmin.edit_handlers import FieldPanel, InlinePanel
  5. from wagtail.wagtailcore.models import Orderable, Page
  6. from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
  7. from wagtail.wagtailsearch import index
  8. class OperatingHours(models.Model):
  9. """
  10. Django model to capture operating hours for a Location
  11. """
  12. MONDAY = 'MON'
  13. TUESDAY = 'TUE'
  14. WEDNESDAY = 'WED'
  15. THURSDAY = 'THU'
  16. FRIDAY = 'FRI'
  17. SATURDAY = 'SAT'
  18. SUNDAY = 'SUN'
  19. DAY_CHOICES = (
  20. (MONDAY, 'MON'),
  21. (TUESDAY, 'TUE'),
  22. (WEDNESDAY, 'WED'),
  23. (THURSDAY, 'THU'),
  24. (FRIDAY, 'FRI'),
  25. (SATURDAY, 'SAT'),
  26. (SUNDAY, 'SUN'),
  27. )
  28. day = models.CharField(
  29. max_length=3,
  30. choices=DAY_CHOICES,
  31. default=MONDAY,
  32. )
  33. opening_time = models.TimeField()
  34. closing_time = models.TimeField()
  35. panels = [
  36. FieldPanel('day'),
  37. FieldPanel('opening_time'),
  38. FieldPanel('closing_time'),
  39. ]
  40. class Meta:
  41. abstract = True
  42. def __str__(self):
  43. return '{}: {} - {}'.format(self.day, self.opening_time, self.closing_time)
  44. class LocationOperatingHours(Orderable, OperatingHours):
  45. """
  46. Operating Hours entry for a Location
  47. """
  48. location = ParentalKey(
  49. 'LocationPage',
  50. related_name='hours_of_operation'
  51. )
  52. class LocationsIndexPage(Page):
  53. """
  54. Index page for locations
  55. """
  56. introduction = models.TextField(
  57. help_text='Text to describe the index page',
  58. blank=True)
  59. image = models.ForeignKey(
  60. 'wagtailimages.Image',
  61. null=True,
  62. blank=True,
  63. on_delete=models.SET_NULL,
  64. related_name='+',
  65. help_text='Location listing image'
  66. )
  67. subpage_types = ['LocationPage']
  68. content_panels = Page.content_panels + [
  69. FieldPanel('introduction'),
  70. ImageChooserPanel('image'),
  71. ]
  72. def get_context(self, request):
  73. context = super(LocationsIndexPage, self).get_context(request)
  74. context['locations'] = LocationPage.objects.descendant_of(
  75. self).live().order_by(
  76. 'title')
  77. return context
  78. class LocationPage(Page):
  79. """
  80. Detail for a specific bakery location.
  81. """
  82. address = models.TextField()
  83. image = models.ForeignKey(
  84. 'wagtailimages.Image',
  85. null=True,
  86. blank=True,
  87. on_delete=models.SET_NULL,
  88. related_name='+'
  89. )
  90. lat_long = models.CharField(
  91. max_length=36,
  92. help_text="Comma separated lat/long. (Ex. 64.144367, -21.939182) \
  93. Right click Google Maps and select 'What\'s Here'",
  94. validators=[
  95. RegexValidator(
  96. regex='^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$',
  97. message='Lat Long must be a comma-separated numeric lat and long',
  98. code='invalid_lat_long'
  99. ),
  100. ]
  101. )
  102. # Search index configuration
  103. search_fields = Page.search_fields + [
  104. index.SearchField('address'),
  105. ]
  106. # Editor panels configuration
  107. content_panels = Page.content_panels + [
  108. FieldPanel('address', classname="full"),
  109. FieldPanel('lat_long'),
  110. ImageChooserPanel('image'),
  111. InlinePanel('hours_of_operation', label="Hours of Operation")
  112. ]
  113. def __str__(self):
  114. return self.title
  115. def opening_hours(self):
  116. hours = self.hours_of_operation.all()
  117. return hours
  118. def get_context(self, request):
  119. context = super(LocationPage, self).get_context(request)
  120. context['lat'] = self.lat_long.split(",")[0]
  121. context['long'] = self.lat_long.split(",")[1]
  122. return context
  123. parent_page_types = ['LocationsIndexPage']