models.py 3.4 KB

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