class Model(PostgreSQLModel): field = pg_fields.IntegerRangeField( choices=[ ['1-50', [((1, 25), '1-25'), ([26, 50], '26-50')]], ((51, 100), '51-100'), ], )
class SpecialtyPizza(models.Model): toppings = postgres_fields.ArrayField(models.CharField(max_length=20), size=4) metadata = postgres_fields.HStoreField() price_range = postgres_fields.IntegerRangeField() sales = postgres_fields.BigIntegerRangeField() available_on = postgres_fields.DateTimeRangeField() season = postgres_fields.DateRangeField()
class Day(models.Model): """ Day of week and its active start and end time and whether it is open or closed Kirjastot.fi API uses closed for both days and periods, don't know which takes precedence """ DAYS_OF_WEEK = ((0, _('Monday')), (1, _('Tuesday')), (2, _('Wednesday')), (3, _('Thursday')), (4, _('Friday')), (5, _('Saturday')), (6, _('Sunday'))) period = models.ForeignKey(Period, verbose_name=_('Period'), db_index=True, related_name='days', on_delete=models.CASCADE) weekday = models.IntegerField(verbose_name=_('Weekday'), choices=DAYS_OF_WEEK) opens = models.TimeField(verbose_name=_('Time when opens'), null=True, blank=True) closes = models.TimeField(verbose_name=_('Time when closes'), null=True, blank=True) length = pgfields.IntegerRangeField( verbose_name=_('Range between opens and closes'), null=True, blank=True, db_index=True) # NOTE: If this is true and the period is false, what then? closed = models.NullBooleanField(verbose_name=_('Closed'), default=False) description = models.CharField(max_length=200, verbose_name=_('description'), null=True, blank=True) class Meta: verbose_name = _("day") verbose_name_plural = _("days") def __str__(self): # FIXME: output date in locale-specific format if self.opens and self.closes: hours = ", {0} - {1}".format(time_format(self.opens, "G:i"), time_format(self.closes, "G:i")) else: hours = "" return "{4}, {3}: {1:%d.%m.%Y} - {2:%d.%m.%Y}, {0}: {3} {5}".format( self.get_weekday_display(), self.period.start, self.period.end, STATE_BOOLS[self.closed], self.period.name, hours) def save(self, *args, **kwargs): if self.opens and self.closes: try: opens = int(self.opens.isoformat().replace(":", "")) closes = int(self.closes.isoformat().replace(":", "")) except AttributeError: opens = int(self.opens.replace(":", "")) closes = int(self.closes.replace(":", "")) self.length = NumericRange(opens, closes) return super(Day, self).save(*args, **kwargs)
class VehicleModel(BasicModel): """ 车辆型号信息 """ class Meta: verbose_name = 'VehicleModel' verbose_name_plural = verbose_name index_together = ['vehicle_type', 'brand', 'series'] db_table = 'k_ls_vehicle_model' ordering = ('-pk', ) model = models.CharField('型号', max_length=200, unique=True) # 车辆品牌 vehicle_type = models.CharField('类型', max_length=100, default='') brand = models.CharField('品牌', max_length=100, default='') series = models.CharField('系列', max_length=100, default='') prices = fields.IntegerRangeField('价格区间(万)', default=(None, None)) count = models.PositiveIntegerField('数量', default=0) objects = VehicleModelManager() @property def summary(self): if any([self.brand, self.series]): desc = f'{self.brand}{self.series} ({self.vehicle_type})' else: desc = self.vehicle_type return desc @property def vehicle_qs(self): qs = Vehicle.objects.filter(model_id=self.pk, usrid__gt=0) return qs def checkout(self): self.count = self.vehicle_qs.count() self.save(update_fields=['count', 'updated_at'])
class Opening(Entity): """Defines fields for recording job opening details. """ entry_hash = models.CharField('Title Hash', max_length=200, unique=True) company = models.ForeignKey(Company, on_delete=models.CASCADE) locations = models.ManyToManyField(Location, blank=True) role_title = models.CharField('Role Title', max_length=100) description = models.TextField() url = models.URLField('Job Url', max_length=200, unique=True) is_remote = models.NullBooleanField('Is Remote') part_time_permitted = models.NullBooleanField('Part-Time Permitted') has_401k = models.NullBooleanField('Has 401k') has_dentalins = models.NullBooleanField('Has Dental Insurance') has_healthins = models.NullBooleanField('Has Health Insurance') salary_range = pgmodels.IntegerRangeField('Salary Range', blank=True, null=True) date_active = models.DateField('Date Active', auto_now=False, auto_now_add=False) date_inactive = models.DateField( 'Date Inactive', auto_now=False, auto_now_add=False, blank=True, null=True ) date_created = models.DateTimeField('Date Created', auto_now=False, auto_now_add=True) tsdocument = search.SearchVectorField('Document') def is_match(self, data: dict): """Returns True if data matches opening details otherwise False. :param data: details to match against this opening instance. :type data: dict """ pattern = re.compile('date_*') exclude_list = ( 'id', 'company', 'locations', 'entry_hash', 'tsdocument' ) field_names = list(filter( lambda f: f not in exclude_list and not pattern.match(f), [f.name for f in self._meta.get_fields()] )) for field in field_names: if ( field in data['job'] and hasattr(self, field) and getattr(self, field) != data['job'][field] ): return False return True def __str__(self): """Returns string representation of the model. """ return f'{self.role_title} at {self.company.name}'
class PostgresFieldsModel(models.Model): arrayfield = fields.ArrayField(models.CharField()) hstorefield = fields.HStoreField() jsonfield = fields.JSONField() rangefield = fields.RangeField() integerrangefield = fields.IntegerRangeField() bigintegerrangefield = fields.BigIntegerRangeField() floatrangefield = fields.FloatRangeField() datetimerangefield = fields.DateTimeRangeField() daterangefield = fields.DateRangeField() def arrayfield_tests(self): sorted_array = self.arrayfield.sort() print(sorted_array) def dictfield_tests(self): print(self.hstorefield.keys()) print(self.hstorefield.values()) print(self.hstorefield.update({'foo': 'bar'})) print(self.jsonfield.keys()) print(self.jsonfield.values()) print(self.jsonfield.update({'foo': 'bar'})) def rangefield_tests(self): print(self.rangefield.lower) print(self.rangefield.upper) print(self.integerrangefield.lower) print(self.integerrangefield.upper) print(self.bigintegerrangefield.lower) print(self.bigintegerrangefield.upper) print(self.floatrangefield.lower) print(self.floatrangefield.upper) print(self.datetimerangefield.lower) print(self.datetimerangefield.upper) print(self.daterangefield.lower) print(self.daterangefield.upper)
def test_model_field_formfield_integer(self): model_field = pg_fields.IntegerRangeField() form_field = model_field.formfield() self.assertIsInstance(form_field, pg_forms.IntegerRangeField)
class Model(PostgreSQLModel): field = pg_fields.IntegerRangeField(choices=[ ["1-50", [((1, 25), "1-25"), ([26, 50], "26-50")]], ((51, 100), "51-100"), ], )
class AntSpecies(Species): """Model of an ant species.""" # colony MONOGYNOUS = 'MONO' POLYGYNOUS = 'POLY' OLIGOGYNOUS = 'OLIG' COLONY_STRUCTURE_CHOICES = ((MONOGYNOUS, _('Monogynous')), (OLIGOGYNOUS, _('Oligogynous')), (POLYGYNOUS, _('Polygynous'))) colony_structure = models.CharField(max_length=4, blank=True, null=True, choices=COLONY_STRUCTURE_CHOICES, verbose_name=_('Colony Structure')) @property def colony_structure_str(self): """Returns the colony structure as a string.""" if self.colony_structure is None: return DEFAULT_NONE_STR else: return dict(self.COLONY_STRUCTURE_CHOICES)[self.colony_structure] worker_polymorphism = models.BooleanField( blank=True, null=True, verbose_name=_('Worker polymorphism')) # founding CLAUSTRAL = 'c' SEMI_CLAUSTRAL = 'sc' SOCIAL_PARASITIC = 'sp' SOCIAL_PARASITIC_CAN_OPEN_PUPAE = 'spp' FOUNDING_CHOICES = ((CLAUSTRAL, _('claustral (queen does not need any food)')), (SEMI_CLAUSTRAL, _('semi-claustral (queen needs to be fed during ' 'founding)')), (SOCIAL_PARASITIC, _('social parasitic (queen needs workers of ' 'suitable ant species)')), (SOCIAL_PARASITIC_CAN_OPEN_PUPAE, _('social parasitic (founding can be ' 'done with pupae of suitable ant species)'))) founding = models.CharField(max_length=3, blank=True, null=True, choices=FOUNDING_CHOICES, verbose_name=_('Founding')) flight_months = models.ManyToManyField( Month, blank=True, verbose_name=_('Nuptial flight months'), ) flight_hour_range = psql_fields.IntegerRangeField( blank=True, null=True, verbose_name=_('Flight hour range'), validators=[ psql_validators.RangeMinValueValidator(1), psql_validators.RangeMaxValueValidator(25) ], help_text=INT_RANGE_HELP_TEXT) MODERATE = 'm' WARM = 'w' STICKY = 's' FLIGHT_CLIMATE_CHOICES = ((MODERATE, _('Moderate temperature')), (WARM, _('Warm temperature')), (STICKY, _('Sticky weather'))) flight_climate = models.CharField(blank=True, null=True, max_length=1, choices=FLIGHT_CLIMATE_CHOICES, verbose_name=_('Flight climate')) @property def flight_months_str(self): """Returns the nuptial flight months as a string.""" if self.flight_months.exists() is False: return DEFAULT_NONE_STR else: return ', '.join(str(month) for month in self.flight_months.all()) LEAVES = 'LEAVES' LEAVES_TEXT = _('Leaves, grass and other vegetables') OMNIVOROUS = 'OMNIVOROUS' OMNIVOROUS_TEXT = _( 'Omnivorous (sugar water, honey, insects, meat, seeds, \ nuts etc.)') SEEDS = 'SEEDS' SEEDS_TEXT = _('Mainly seeds and nuts but dead insects and sugar water, \ honey too.') SUGAR_INSECTS = 'SUGAR_INSECTS' SUGAR_INSECTS_TEXT = _('Insects, meat, sugar water, honey etc.') NUTRITION_CHOICES = ((LEAVES, LEAVES_TEXT), (OMNIVOROUS, OMNIVOROUS_TEXT), (SEEDS, SEEDS_TEXT), (SUGAR_INSECTS, SUGAR_INSECTS_TEXT)) nutrition = models.CharField(max_length=20, blank=True, null=True, choices=NUTRITION_CHOICES, verbose_name=_('Nutrition')) LONG_HIBERNATION = 'LONG' LONG_HIBERNATION_TEXT = _('yes: end of september until end of march') SHORT_HIBERNATION = 'SHORT' SHORT_HIBERNATION_TEXT = _('yes: end of november until end of' ' february') NO_HIBERNATION = 'NO' NO_HIBERNATION_TEXT = _('No') HIBERNATION_CHOICES = ((NO_HIBERNATION, NO_HIBERNATION_TEXT), (LONG_HIBERNATION, LONG_HIBERNATION_TEXT), (SHORT_HIBERNATION, SHORT_HIBERNATION_TEXT)) hibernation = models.CharField(max_length=5, blank=True, null=True, choices=HIBERNATION_CHOICES, verbose_name=_('Hibernation required')) information_complete = models.BooleanField( default=False, verbose_name=_('Information complete')) nest_temperature = psql_fields.IntegerRangeField( blank=True, null=True, validators=[ psql_validators.RangeMinValueValidator(0), psql_validators.RangeMaxValueValidator(41) ], verbose_name=_('Nest temperature (℃)'), help_text=INT_RANGE_HELP_TEXT) nest_humidity = psql_fields.IntegerRangeField( blank=True, null=True, validators=[ psql_validators.RangeMinValueValidator(0), psql_validators.RangeMaxValueValidator(100) ], verbose_name=_('Nest relative humidity (%)'), help_text=INT_RANGE_HELP_TEXT) outworld_temperature = psql_fields.IntegerRangeField( blank=True, null=True, validators=[ psql_validators.RangeMinValueValidator(0), psql_validators.RangeMaxValueValidator(41) ], verbose_name=_('Outworld temperature (℃)'), help_text=INT_RANGE_HELP_TEXT) outworld_humidity = psql_fields.IntegerRangeField( blank=True, null=True, validators=[ psql_validators.RangeMinValueValidator(0), psql_validators.RangeMaxValueValidator(100) ], verbose_name=_('Outworld relative humidty (%)'), help_text=INT_RANGE_HELP_TEXT) created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True) created_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='created_ant_species', null=True, blank=True, on_delete=models.SET_NULL) updated_at = models.DateTimeField(auto_now=True, null=True) updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='updated_ant_species', null=True, blank=True, on_delete=models.SET_NULL) @property def main_image(self): return self.images.filter(main_image=True).first() def get_absolute_url(self): """Return the url to detail page.""" return reverse('ant_detail', args=[self.slug]) @property def antwiki_url(self): """Returns the url to the antwiki.org page for that ant species.""" return 'http://www.antwiki.org/wiki/{}' \ .format(self.name.replace(' ', '_')) objects = AntSpeciesManager() class Meta(SpeciesMeta): pass