class AllFields(models.Model): bigintegerfield = models.BigIntegerField() binaryfield = models.BinaryField() booleanfield = models.BooleanField() charfield = models.CharField() commaseparatedintegerfield = models.CommaSeparatedIntegerField() datefield = models.DateField() datetimefield = models.DateTimeField() decimalfield = models.DecimalField() durationfield = models.DurationField() emailfield = models.EmailField() filefield = models.FileField() filepathfield = models.FilePathField() floatfield = models.FloatField() genericipaddressfield = models.GenericIPAddressField() ipaddressfield = models.IPAddressField() imagefield = models.ImageField() integerfield = models.IntegerField() nullbooleanfield = models.NullBooleanField() positiveintegerfield = models.PositiveIntegerField() positivesmallintegerfield = models.PositiveSmallIntegerField() slugfield = models.SlugField() smallintegerfield = models.SmallIntegerField() textfield = models.TextField() timefield = models.TimeField() urlfield = models.URLField() uuidfield = models.UUIDField() arrayfield = ps_fields.ArrayField(models.CharField()) cicharfield = ps_fields.CICharField() ciemailfield = ps_fields.CIEmailField() citextfield = ps_fields.CITextField() hstorefield = ps_fields.HStoreField() class Meta: app_label = "tests"
class Publication(models.Model): ID_FORMAT = "{institution}:{date}:{identifier}" __identifier_length = 128 __id_length = ( Institution._meta.get_field('id').max_length + 10 # date + __identifier_length + 2 # separators in ID_FORMAT ) id = models.CharField(max_length=__id_length, primary_key=True) identifier = models.CharField(max_length=__identifier_length) title = models.CharField(max_length=2048) # TODO: switch this to an enum on the db side type = models.CharField(PUBLICATION_TYPES, max_length=5) institution = models.ForeignKey(Institution) date = models.DateField(db_index=True) description = models.TextField(blank=True) feedback_days = models.PositiveSmallIntegerField(null=True) contact = pgfields.HStoreField(default=dict) # (validators=[ # AllowedKeysValidator('tel', 'email', 'addr'), # ]) submitted_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True) def __str__(self): return "%s - %s" % (self.date, self.title) def save(self, *args, **kwargs): if not self.id: self.id = self.ID_FORMAT.format(institution=self.institution.id, date=self.date.isoformat(), identifier=self.identifier) super().save(*args, **kwargs)
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 Company(models.Model): name = models.CharField('nom', max_length=100) slug = models.SlugField(unique=True) group = models.ForeignKey(Group, verbose_name='groupe', related_name='companies') type = models.ForeignKey(ContactType, verbose_name='type', null=True, related_name='companies') comments = models.TextField('commentaires') properties = fields.HStoreField('propriétés', default={}) creation_date = models.DateTimeField('date de création', auto_now_add=True) update_date = models.DateTimeField('date de mise à jour', auto_now=True) active = models.BooleanField('actif', default=True, db_index=True) author = models.ForeignKey(User, verbose_name='créateur', related_name='added_companies') def __str__(self): return self.name def get_absolute_url(self): return reverse('contacts:company-detail', kwargs={'slug': self.slug}) def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) return super().save(*args, **kwargs) class Meta: verbose_name = 'société'
class Model(models.Model): author = models.ForeignKey(User, on_delete=models.CASCADE) model_id = models.IntegerField() revision = models.IntegerField() title = models.CharField(max_length=32) building_id = models.CharField(max_length=1024, null=True) description = models.CharField(max_length=512) rendered_description = models.CharField(max_length=1024) upload_date = models.DateField(auto_now_add=True) location = models.OneToOneField(Location, null=True, default=None, on_delete=models.CASCADE) license = models.IntegerField() categories = models.ManyToManyField(Category) tags = fields.HStoreField(default={}) rotation = models.FloatField(default=0.0) scale = models.FloatField(default=1.0) translation_x = models.FloatField(default=0.0) translation_y = models.FloatField(default=0.0) translation_z = models.FloatField(default=0.0) is_hidden = models.BooleanField(default=False) class Meta: app_label = 'mainapp'
class LatestModel(pg.MaterializedView): author = models.ForeignKey(User, on_delete=models.CASCADE) model_id = models.IntegerField() building_id = models.CharField(max_length=1024) revision = models.IntegerField() title = models.CharField(max_length=32) description = models.CharField(max_length=512) rendered_description = models.CharField(max_length=1024) upload_date = models.DateField(auto_now_add=True) location = models.OneToOneField(Location, null=True, default=None, on_delete=models.CASCADE) license = models.IntegerField() categories = models.ManyToManyField(Category) tags = fields.HStoreField(default={}) rotation = models.FloatField(default=0.0) scale = models.FloatField(default=1.0) translation_x = models.FloatField(default=0.0) translation_y = models.FloatField(default=0.0) translation_z = models.FloatField(default=0.0) is_hidden = models.BooleanField(default=False) concurrent_index = 'id' sql = """ SELECT model.id AS id, model.model_id AS model_id, model.building_id AS building_id, model.revision AS revision, model.title AS title, model.description AS description, model.rendered_description AS rendered_description, model.upload_date AS upload_date, model.location_id as location_id, model.license AS license, model.rotation AS rotation, model.scale AS scale, model.translation_x AS translation_x, model.translation_y AS translation_y, model.translation_z AS translation_z, model.author_id AS author_id, model.tags AS tags, model.is_hidden AS is_hidden FROM mainapp_model model LEFT JOIN mainapp_model newer ON model.model_id = newer.model_id AND model.revision < newer.revision WHERE newer.revision is NULL """ class Meta: app_label = 'mainapp' db_table = 'mainapp_latestmodel' managed = False
class WebEvent(TimeTrackedModel): modified = None METHOD_TYPES = Choices( 'GET', 'POST', ) DEVICE_TYPES = Choices( 'PC', 'MOBILE', 'TABLET', 'BOT', 'UNKNOWN', ) visitor = models.ForeignKey('Visitor', on_delete=models.PROTECT) data = pg_fields.JSONField(default=dict, encoder=DjangoQuerysetJSONEncoder) marketing_params = pg_fields.HStoreField(default=dict) referrer = models.URLField(max_length=2048) url = models.URLField(max_length=2048) url_kwargs = pg_fields.HStoreField(default=dict) url_name = models.CharField(max_length=100) response_data = pg_fields.HStoreField(default=dict) status_code = models.IntegerField() method = models.CharField(max_length=6, choices=METHOD_TYPES) # from user agent browser = models.CharField(max_length=30) browser_version = models.CharField(max_length=30) os = models.CharField(max_length=100) os_version = models.CharField(max_length=30) device_model = models.CharField(max_length=30) device_type = models.CharField(max_length=10, choices=DEVICE_TYPES) ip_address = models.GenericIPAddressField(max_length=39, null=True) ip_country = CountryField() ip_region = models.CharField(max_length=255) ip_city = models.CharField(max_length=255) def __str__(self): return f'{self.visitor_id} - {self.method} - {self.url_name}' class Meta: ordering = ['created']
class Preference(models.Model): user = models.OneToOneField(User, models.CASCADE, primary_key=True) home_layout = postgres.ArrayField( postgres.HStoreField(), blank=True, default=list, ) def get_serialized_home_layout(self): return str(self.home_layout).replace("\'", "\"") def __str__(self): return str(self.user)
class AbstractContactList(AbstractOwnedModel): author = models.ForeignKey(MunchUser, verbose_name='auteur') properties = fields.HStoreField('propriétés', default={}) source_type = models.CharField(blank=True, max_length=100, validators=[slug_regex_validator]) source_ref = models.CharField(blank=True, max_length=200) uuid = models.UUIDField(editable=False, default=uuid.uuid4) owner_path = 'author__organization' author_path = 'author' class Meta: abstract = True @property def subscription(self): return urljoin(settings.APPLICATION_URL.strip('/'), reverse('subscription', kwargs={'uuid': self.uuid}))
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)
class AbstractContact(AbstractOwnedModel): PENDING = 'pending' BOUNCED = 'bounced' EXPIRED = 'expired' OK = 'ok' CONSUMED = 'consumed' properties = fields.HStoreField('propriétés', default={}) address = models.EmailField('adresse e-mail') creation_date = models.DateTimeField('date de création', auto_now_add=True) update_date = models.DateTimeField('date de modification', auto_now=True) uuid = models.UUIDField(editable=False, default=uuid.uuid4) status = models.CharField('statut', max_length=50, choices=((PENDING, 'en attente'), (BOUNCED, 'échec bounce'), (EXPIRED, 'expiré'), (OK, 'ok'), (CONSUMED, 'consommé')), default=PENDING) subscription_ip = models.GenericIPAddressField('adresse IP d’envoi', default='127.0.0.1') class Meta(AbstractOwnedModel.Meta): abstract = True verbose_name = 'contact' def apply_policies(self): """ Executes each policy registered with the ContactList. """ if getattr(self, self.contact_list_path).policies.count() == 0: self.status = self.OK self.save() else: policies = getattr(self, self.contact_list_path).policies.all() policies_names = [p.name for p in policies] for policy in policies: policy.apply(self, policies_names)
class TestModel(models.Model): big_integer_field = models.BigIntegerField() binary_field = models.BinaryField() boolean_field = models.BooleanField() char_field = models.CharField() date_field = models.DateField() date_time_field = models.DateTimeField() decimal_field = models.DecimalField(max_digits=1, decimal_places=1) duration_field = models.DurationField() email_field = models.EmailField() file_field = models.FileField() file_path_field = models.FilePathField() float_field = models.FloatField() image_field = models.ImageField() integer_field = models.IntegerField() generic_ip_field = models.GenericIPAddressField() null_boolean_field = models.NullBooleanField() positive_integer_field = models.PositiveIntegerField() positive_small_integer_field = models.PositiveSmallIntegerField() slug_field = models.SlugField() small_integer_field = models.SmallIntegerField() text_field = models.TextField() time_field = models.TimeField() url_field = models.URLField() uuid_field = models.UUIDField() array_of_char_field = postgres_fields.ArrayField( models.CharField(), ) array_of_int_field = postgres_fields.ArrayField( models.IntegerField(), ) citext_field = ( postgres_fields.CITextField() if django.VERSION[0:2] >= (1, 11) else models.CharField() ) hstore_field = postgres_fields.HStoreField() json_field = postgres_fields.JSONField()
class Contact(models.Model): firstname = models.CharField('prénom', max_length=100) lastname = models.CharField('nom', max_length=100, blank=True) slug = models.SlugField() company = models.ForeignKey(Company, verbose_name='société', null=True, blank=True, related_name='contacts') group = models.ForeignKey(Group, verbose_name='groupe', related_name='contacts') type = models.ForeignKey(ContactType, verbose_name='type', null=True, related_name='contacts') comments = models.TextField('commentaires', blank=True) properties = fields.HStoreField('propriétés', default={}) creation_date = models.DateTimeField('date de création', auto_now_add=True) update_date = models.DateTimeField('date de mise à jour', auto_now=True) active = models.BooleanField('actif', default=True, db_index=True) author = models.ForeignKey(User, verbose_name='créateur', related_name='added_contacts') def __str__(self): return '{} {}'.format(self.firstname, self.lastname) def get_comments(self): return bleach.clean(bleach.linkify(markdown(self.comments)), ALLOWED_TAGS) @method_cache(60) def get_properties(self): props = Properties.objects.filter(type='contact', group=self.group)\ .only('name', 'order') props_order = {} for p in props: props_order[p.name] = p.order return {k: bleach.linkify(v, parse_email=True) for k, v in sorted(self.properties.items(), key=lambda i: props_order.get(i, 0))} @method_cache(60) def get_displayed_properties(self): displayed = OrderedDict() props = Properties.objects.filter(type='contact', group=self.group, display_on_list=True)\ .only('name', 'order') props_order = {} for p in props: displayed[p.name] = '' props_order[p.name] = p.order for k, v in sorted(self.properties.items(), key=lambda i: props_order.get(i, 0)): if k in displayed: displayed[k] = bleach.linkify(v, parse_email=True) return displayed def active_alerts(self): return Alert.objects.filter(contact=self, done=False, date__gt=timezone.now()) def get_glyphicon(self): return 'user' def get_absolute_url(self): return reverse('contacts:contact-detail', kwargs={'slug': self.slug}) def save(self, *args, **kwargs): if not self.slug: company = '{} '.format(self.company) if self.company else '' self.slug = slugify('{}{} {}'.format(company, self.firstname, self.lastname)) return super().save(*args, **kwargs) @classmethod def import_data(cls, data, mapping, properties, user): logger = logging.getLogger('import.contact') logger.debug('Début de l’import de contacts') company_cache = ImportCache(Company, user, logger) type_cache = ImportCache(ContactType, user, logger) prop_cache = ImportCache(Properties, user, logger) imported_objects = {} updated_objects = {} errors = 0 for row in data: try: with transaction.atomic(): row = apply_mapping(row, mapping) if row['firstname'] != '' or row['lastname'] != '': args = {} args['company'] = company_cache.get(row.pop('company')) args['type'] = type_cache.get(row.pop('type')) args['firstname'] = row.pop('firstname') args['lastname'] = row.pop('lastname') args['comments'] = row.pop('comments') args['properties'] = {} args['author'] = user args['group'] = user.default_group.group for prop, prop_value in row.items(): if prop is not None and\ (properties is None or prop in properties): prop_cache.get({'type': 'contact', 'name': prop}) args['properties'][prop] = prop_value # do we have to create an object, or is there an # existing one to update? try: contact = cls.get_queryset(user).get( company=args['company'], firstname=args['firstname'], lastname=args['lastname']) contact.properties.update(args['properties']) contact.type = args['type'] contact.comments = args['comments'] contact.save() updated_objects[contact.pk] = contact logger.info('Modification de contact : {}' .format(contact)) except cls.DoesNotExist: contact = cls.objects.create(**args) logger.info('Création de contact : {}' .format(contact)) imported_objects[contact.pk] = contact else: logger.info('Contact sans nom : on passe') except DataImportError as e: logger.error('Erreur lors de l’import du contact : {}' .format(e)) errors += 1 except Exception as e: logger.error('Erreur inattendue ({}) : {}' .format(e.__class__.__name__, e)) errors += 1 logger.debug('Fin de l’import de contacts ({} créés, {} modifiés, ' '{} erreurs)' .format(len(imported_objects), len(updated_objects), errors)) return (list(imported_objects.values()), list(updated_objects.values()), errors) @classmethod def export_data(self, qs): export = [] fields = {'firstname': None, 'lastname': None, 'company': 'company__name', 'type': 'type__name', 'comments': None, } logger = logging.getLogger('export.contact') for obj in qs: logger.debug('Beginning export of contact {}'.format(obj)) row = OrderedDict() for key, mapping in fields.items(): if mapping is None: row[key] = getattr(obj, key) else: remaining_fields = mapping.split('__') value = obj while len(remaining_fields) >= 1: try: value = getattr(value, remaining_fields.pop(0)) except AttributeError: value = '' row[key] = value if isinstance(row[key], bool): row[key] = int(row[key]) elif hasattr(row[key], 'isoformat'): row[key] = row[key].isoformat() # properties fetch row.update(obj.properties) export.append(row) return export @classmethod def get_queryset(cls, user, qs=None): if qs is None: qs = cls.objects return qs.filter(group_id=user.default_group.group_id) def is_owned(self, user, perm=None): return self.group.id == user.default_group.group_id class Meta: verbose_name = 'contact' words = {'of': 'de ', 'of_a': 'd’un ', 'of_the': 'du ', 'an': 'un', } get_latest_by = 'update_date' ordering = ['firstname', 'lastname'] unique_together = (('slug', 'group'), ) permissions = (('view_contact', 'Can view a contact'), ) select_related = ('company', 'type', 'author', )
class Movie(Resource): ''' Can either be movie or series. ''' # widely recognized name, usually in Chinese title = models.CharField(_("title"), max_length=200) # original name, for books in foreign language orig_title = models.CharField(_("original title"), blank=True, default='', max_length=200) other_title = postgres.ArrayField( models.CharField(_("other title"), blank=True, default='', max_length=100), null=True, blank=True, default=list, ) imdb_code = models.CharField(blank=True, max_length=10, null=True, unique=True, db_index=True) director = postgres.ArrayField( models.CharField(_("director"), blank=True, default='', max_length=100), null=True, blank=True, default=list, ) playwright = postgres.ArrayField( models.CharField(_("playwright"), blank=True, default='', max_length=100), null=True, blank=True, default=list, ) actor = postgres.ArrayField( models.CharField(_("actor"), blank=True, default='', max_length=100), null=True, blank=True, default=list, ) genre = postgres.ArrayField( models.CharField(_("genre"), blank=True, default='', choices=MovieGenreEnum.choices, max_length=50), null=True, blank=True, default=list, ) showtime = postgres.ArrayField( # HStoreField stores showtime-region pair postgres.HStoreField(), null=True, blank=True, default=list, ) site = models.URLField(_('site url'), blank=True, default='', max_length=200) # country or region area = postgres.ArrayField( models.CharField( _("country or region"), blank=True, default='', max_length=100, ), null=True, blank=True, default=list, ) language = postgres.ArrayField( models.CharField( blank=True, default='', max_length=100, ), null=True, blank=True, default=list, ) year = models.PositiveIntegerField(null=True, blank=True) duration = models.CharField(blank=True, default='', max_length=200) cover = models.ImageField(_("poster"), upload_to=movie_cover_path, default=DEFAULT_MOVIE_IMAGE, blank=True) ############################################ # exclusive fields to series ############################################ season = models.PositiveSmallIntegerField(null=True, blank=True) # how many episodes in the season episodes = models.PositiveIntegerField(null=True, blank=True) # deprecated # tv_station = models.CharField(blank=True, default='', max_length=200) single_episode_length = models.CharField(blank=True, default='', max_length=100) ############################################ # category identifier ############################################ is_series = models.BooleanField(default=False) def __str__(self): if self.year: return self.title + f"{self.year}" else: return self.title def get_tags_manager(self): return self.movie_tags def get_genre_display(self): translated_genre = [] for g in self.genre: translated_genre.append(MovieGenreTranslator[g]) return translated_genre @property def verbose_category_name(self): if self.is_series: return _("剧集") else: return _("电影")
class StockKeepingUnit(TimeStampedModel): _active = models.BooleanField( _('active'), default=True, ) attributes = pg_fields.HStoreField(default=dict, ) # "image": null, initial_quantity = models.PositiveIntegerField( null=True, blank=True, ) # "package_dimensions": null, product = models.ForeignKey( Product, related_name='skus', ) prices = models.ManyToManyField( Price, related_name='products', ) active = QueryManager(_active=True, product__active=True) objects = models.Manager() class Meta: unique_together = (('attributes', 'product'), ) def __str__(self): return str(self.product) + ': ' + '-'.join(self.attributes.values()) def delete(self, using=None, keep_parents=False): if self.orderitem_set.all().exists(): self._active = False self.save(using=using, update_fields=['_active']) return 0 else: return super().delete(using, keep_parents) @property def is_active(self): return self._active and self.product.active @cached_property def _price(self): return Price.timeframed.filter( products=self, amount_currency=settings.DEFAULT_CURRENCY, ).order_by( '-start', 'id', ).last() @property def price(self): return (self._price is not None) and self._price.amount @property def vat_amount(self): return (self._price is not None) and self._price.vat_amount def clean(self): KeysValidator( keys=self.product.attributes, strict=True, )(self.attributes)
(models.BigIntegerField(), 5, 5, int), (models.BooleanField(), True, True, bool), (models.CharField(), 'foo', 'foo', str), (models.DateTimeField(), datetime(2018, 11, 1), '2018-11-01T00:00:00', str), (models.DecimalField(), Decimal('13.37'), '13.37', str), (models.EmailField(), '*****@*****.**', '*****@*****.**', str), (models.FloatField(), 5.5, 5.5, float), (models.IntegerField(), 5, 5, int), (models.NullBooleanField(), True, True, bool), (models.PositiveIntegerField(), 5, 5, int), (models.PositiveSmallIntegerField(), 5, 5, int), (models.SlugField(), 'foo', 'foo', str), (models.SmallIntegerField(), 5, 5, int), (models.TextField(), 'foo', 'foo', str), (psql_fields.HStoreField(), { 'foo': 'bar' }, { 'foo': 'bar' }, dict), ]) def test_field_is_correctly_serialized(field, value, expected, expected_type, django_setup): class TestModel(models.Model): foo = field class TestSerializer(DjangoModelSerializer): class Meta: model = TestModel fields = ['foo']
class SavedSearch(models.Model): group = models.ForeignKey(Group, verbose_name='groupe', related_name='searches') name = models.CharField('nom', max_length=32) slug = models.SlugField() type = models.CharField('type', max_length=32, choices=SEARCH_CHOICES) display_in_menu = models.BooleanField('affichage dans le menu', default=True) data = fields.HStoreField('données de recherche', default={}) author = models.ForeignKey(User, verbose_name='créateur', related_name='saved_searches') results_count = models.PositiveIntegerField('nombre de résultats', default=0) creation_date = models.DateTimeField('date de création', auto_now_add=True) update_date = models.DateTimeField('date de mise à jour', auto_now=True) def __str__(self): return self.name def get_absolute_url(self): return reverse('contacts:search-detail', kwargs={'slug': self.slug}) def get_search_model(self): return getattr(sys.modules[__name__], self.type) @classmethod def get_queryset(cls, user, qs=None): if qs is None: qs = cls.objects return qs.filter(group_id=user.default_group.group_id) def is_owned(self, user, perm=None): return self.group.id == user.default_group.group_id def get_search_queryset(self, user): from . import forms model = self.get_search_model() if hasattr(model, 'get_queryset'): qs = model.get_queryset(user) else: qs = model.objects.all() form_class = getattr(forms, '{}SearchForm'.format(self.type)) form = form_class(data=self.data) qs = form.search(qs) self.results_count = qs.count() self.save() return qs def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.name) return super().save(*args, **kwargs) class Meta: verbose_name = 'recherche sauvegardée' words = {'of': 'de ', 'of_a': 'd’une ', 'of_the': 'de la ', 'an': 'une', } verbose_name_plural = 'recherches sauvegardées' ordering = ['name'] unique_together = (('slug', 'group'), ) permissions = (('view_savedsearch', 'Can view a saved search'), )