11import uuid
2- import json
3- from django .utils .functional import cached_property
42from django .contrib .gis .db import models
53from django .utils .translation import gettext_lazy as _
64from wagtailgeowidget .panels import LeafletPanel
75from wagtailgeowidget .helpers import geosgeometry_str_to_struct
8- from wagtail .admin .panels import FieldPanel
6+ from wagtail .admin .panels import FieldPanel , MultiFieldPanel
7+ from wagtail .fields import RichTextField , StreamField
8+ from wagtail .snippets .models import register_snippet
9+
10+ from .blocks import ExtremeBlock
11+
12+ # @register_snippet
13+ class DailyWeather (models .Model ):
14+ issued_on = models .DateField (auto_now_add = True , null = True )
15+ forecast_date = models .DateField (_ ("Forecast Date" ), auto_now = False , auto_now_add = False )
16+ forecast_desc = RichTextField (verbose_name = _ ('Weather Forecast Description' ))
17+ summary_date = models .DateField (_ ("Summary Date" ), auto_now = False , auto_now_add = False )
18+ summary_desc = RichTextField (verbose_name = _ ('Weather Summary Description' ))
19+ extreme_date = models .DateField (_ ("Extreme Date" ), auto_now = False , auto_now_add = False , null = True , blank = True )
20+ extremes = StreamField ([
21+ ('extremes' , ExtremeBlock ())
22+ ], use_json_field = True )
23+
24+ panels = [
25+ MultiFieldPanel ([
26+ FieldPanel ('summary_date' ),
27+ FieldPanel ('summary_desc' ),
28+ ], heading = "Weather Summary" ),
29+ MultiFieldPanel ([
30+ FieldPanel ('forecast_date' ),
31+ FieldPanel ('forecast_desc' ),
32+ ], heading = "Weather Forecast" ),
33+ MultiFieldPanel ([
34+ FieldPanel ('extreme_date' ),
35+ FieldPanel ('extremes' )
36+ ], heading = "Extremes" )
37+
38+
39+ ]
40+
41+ def __str__ (self ) -> str :
42+ return f'Daily Weather - Issued on { self .issued_on .strftime ("%Y-%m-%d" )} '
43+
44+
945
1046# Create your models here.
1147class City (models .Model ):
@@ -30,62 +66,66 @@ class Meta:
3066 def __str__ (self ) -> str :
3167 return self .name
3268
33- @cached_property
34- def point (self ):
35- return json .dumps (geosgeometry_str_to_struct (str (self .location )))
36-
3769 @property
38- def lat (self ):
39- return self .point ['y' ]
70+ def coordinates (self ):
71+ location = geosgeometry_str_to_struct (str (self .location ))
72+ return [location ['x' ],location ['y' ] ]
4073
41- @property
42- def lng (self ):
43- return self .point ['x' ]
44-
45-
46- class ConditionCategory (models .Model ):
47- title = models .CharField (max_length = 50 , help_text = _ ("Weather Condition Title" ), verbose_name = _ ("Weather Condtion Title" ))
48- short_name = models .CharField (max_length = 50 , help_text = _ ("Weather Condition Short Name (helpgul for yr.no weather api)" ), verbose_name = _ ("Weather Condtion Short Name" ), null = True , blank = True , editable = False )
49- description = models .CharField (max_length = 250 , blank = True , null = True , verbose_name = _ ("Description" ))
50- icon_image = models .ForeignKey (
51- 'wagtailimages.Image' ,
52- null = True ,
53- blank = False ,
54- on_delete = models .SET_NULL ,
55- related_name = '+' ,
56- verbose_name = _ ("Icon image" )
57- )
58-
59-
60- class Meta :
61- verbose_name = _ ("Weather Condition Category" )
62- verbose_name_plural = _ ("Weather Condition Categories" )
63-
64-
65- def __str__ (self ):
66- return self .title
67-
68-
69- def save (self , * args , ** kwargs ):
70- if not self .short_name :
71- self .short_name = self .icon_image .file .name .split ('/' )[- 1 ].split ('.' )[0 ]
72- super (ConditionCategory , self ).save (* args , ** kwargs )
74+ class Forecast (models .Model ):
75+ CONDITION_CHOICES = (
76+ ('clearsky' , 'Clear sky' ),
77+ ('cloudy' ,'Cloudy' ),
78+ ('fair' ,'Fair' ),
79+ ('fog' ,'Fog' ),
80+ ('heavyrain' ,'Heavy Rain' ),
81+ ('heavyrainandthunder' ,'Heavy Rain and Thunder' ),
82+ ('heavyrainshowers' ,'Heavy Rain Showers' ),
83+ ('heavyrainshowersandthunder' ,'Heavy Rain Showers and Thunder' ),
84+ ('heavysleet' ,'Heavy Sleet' ),
85+ ('heavysleetandthunder' ,'Heavy Sleet and Thunder' ),
86+ ('heavysleetshowers' ,'Heavy Sleet Showers' ),
87+ ('heavysleetshowersandthunder' ,'Heavy Sleet Showers and Thunder' ),
88+ ('heavysnow' ,'Heavy Snow' ),
89+ ('heavysnowandthunder' ,'Heavy Snow and Thunder' ),
90+ ('heavysnowshowers' ,'Heavy Snow Showers' ),
91+ ('heavysnowshowersandthunder' ,'Heavy Snow Showers and Thunder' ),
92+ ('lightrain' ,'Light Rain' ),
93+ ('lightrainandthunder' ,'Light Rain and Thunder' ),
94+ ('lightrainshowers' ,'Light Rain Showers' ),
95+ ('lightrainshowersandthunder' ,'Light Rain Showers and Thunder' ),
96+ ('lightsleet' ,'Light Sleet' ),
97+ ('lightsleetandthunder' ,'Light Sleet and Thunder' ),
98+ ('lightsleetshowers' ,'Light Sleet Showers' ),
99+ ('lightsleetshowersandthunder' ,'Light Sleet Showers and Thunder' ),
100+ ('lightsnowshowersandthunder' ,'Light Snow Showers and Thunder' ),
101+ ('partlycloudy' ,'Partly Cloudy' ),
102+ ('rain' ,'Rain' ),
103+ ('rainandthunder' ,'Rain and Thunder' ),
104+ ('rainshowers' ,'Rain showers' ),
105+ ('rainshowersandthunder' ,'Rain Showes and Thunder' ),
106+ ('sleet' ,'Sleet' ),
107+ ('sleetandthunder' ,'Sleet and Thunder' ),
108+ ('sleetshowers' ,'Sleet Showers' ),
109+ ('sleetshowersandthunder' ,'Sleet Showes and Thunder' ),
110+ ('snow' ,'Snow' ),
111+ ('snowandthunder' ,'Snow and Thunder' ),
112+ ('snowshowers' ,'Snow Showers' ),
113+ ('snowshowersandthunder' ,'Snow Showers and Thunder' ),
73114
115+ )
74116
75- class Forecast (models .Model ):
76117 city = models .ForeignKey (City , on_delete = models .CASCADE , verbose_name = _ ("City" ))
77118 forecast_date = models .DateField ( auto_now = False , auto_now_add = False , verbose_name = _ ("Forecasts Date" ))
78119 max_temp = models .IntegerField (verbose_name = _ ("Maximum Temperature" ), blank = True )
79120 min_temp = models .IntegerField (verbose_name = _ ("Minimum Temperaure" ), blank = True )
80121 wind_direction = models .IntegerField (verbose_name = _ ("Wind Direction" ), blank = True , null = True )
81122 wind_speed = models .IntegerField (verbose_name = _ ("Wind Speed" ), blank = True , null = True )
82- # condition = models.CharField(verbose_name=_("General Weather Condition", max_length=255, blank=True, help_text="E.g Light Showers", default="Light Showers")
83- condition = models .ForeignKey (ConditionCategory , verbose_name = _ ("General Weather Condition" ), on_delete = models .CASCADE , help_text = _ ("E.g Light Showers" ), null = True )
123+ condition = models .CharField (choices = CONDITION_CHOICES , verbose_name = _ ("General Weather Condition" ), help_text = _ ("E.g Light Showers" ), null = True , max_length = 255 )
84124
85125 class Meta :
86126 verbose_name = _ ("Forecast" )
87127 verbose_name_plural = _ ("Forecasts" )
88- unique_together = ('city' , 'forecast_date' )
128+ # unique_together = (( 'city', 'forecast_date') )
89129
90130 panels = [
91131 FieldPanel ("city" ),
@@ -100,3 +140,4 @@ class Meta:
100140 # def __str__(self):
101141 # return f"{self.city} - {self.forecast_date}"
102142
143+
0 commit comments