class Tag(models.Model): title =models.CharField(max_length=50) slug = models.SlugField(max_length=50, unique=True) def __str__(self): return '{}'.format (self.title)
class Category(models.Model): ''' The ``Category`` model represents a category within a specific ``Catalog`` object. Categories contain a ForeignKey to their catalog, as well as an optional ForeignKey to another category that will serve as a parent category. ''' active = models.BooleanField(_('is active'), default=True) parent = models.ForeignKey('self', blank=True, null=True, related_name='children', db_index=True) name = models.CharField(max_length=300) slug = models.SlugField(max_length=150) path = models.CharField(_("Path"), max_length=255, blank=True, db_index=True) ordering = models.PositiveIntegerField(_('ordering'), default=0) description = models.TextField(blank=True) template = models.CharField(_(u"Category template"), max_length=255, blank=True, null=True, choices=CATEGORY_TEMPLATES, default=CATEGORY_TEMPLATES[0][0]) separator = '::' objects = CategoryManager() class Meta: ordering = ['parent__id', 'ordering', 'name'] verbose_name = _('Category') verbose_name_plural = _('Categories') def __unicode__(self): name_list = [cat.name for cat in self.get_ancestors()] name_list.append(self.name) return self.separator.join(name_list) @models.permalink def get_absolute_url(self): return ('catalog.views.category_view', [self.path]) def active_products(self, include_children=False, **kwargs): if not include_children: qry = self.products.all() else: cats = self.get_descendants(include_self=True) qry = Product.objects.filter(categories__in=cats) return qry.filter(active=True, **kwargs) @property def main_image(self): img = False if self.images.count() > 0: img = self.images.order_by('sort')[0] else: if self.parent_id and self.parent != self: img = self.parent.main_image if not img: #This should be a "Image Not Found" placeholder image try: img = CategoryImage.objects.filter( category__isnull=True).order_by('sort')[0] except IndexError: pass return img def get_children(self): """ :returns: A queryset of all the node's children """ return self.__class__.objects.filter(parent=self) def get_ancestors(self): """ :returns: A *list* containing the current node object's ancestors, starting by the root node and descending to the parent. """ ancestors = [] node = self.parent while node: ancestors.append(node) node = node.parent ancestors.reverse() return ancestors def get_root(self): """ :returns: the root node for the current node object. """ ancestors = self.get_ancestors() if ancestors: return ancestors[0] return self def _flatten(self, L): """ Taken from a python newsgroup post """ if type(L) != type([]): return [L] if L == []: return L return self._flatten(L[0]) + self._flatten(L[1:]) def _recurse_for_children(self, node): children = [] children.append(node) for child in node.children.active(): if child != self: children_list = self._recurse_for_children(child) children.append(children_list) return children def get_descendants(self, include_self=False): """ Gets a list of all of the children categories. """ children_list = self._recurse_for_children(self) # first item is self ix = 0 if include_self else 1 flat_list = self._flatten(children_list[ix:]) return flat_list def save(self, *args, **kwargs): current_path = self.path slug = u'%s' % self.slug if self.parent: self.path = u'%s/%s' % (self.parent.path, slug) else: self.path = u'%s' % slug super(Category, self).save(*args, **kwargs) # Update descendants only if path changed if current_path != self.path: for child in self.get_children(): child.path = child.path.replace(current_path, self.path, 1) child.save()
class Channel(models.Model): title = models.CharField( _('Title'), max_length=100, unique=True, help_text=_("Please choose a title as short and accurate as " "possible, reflecting the main subject / context " "of the content.(max length : 100 characters)")) slug = models.SlugField( _('Slug'), unique=True, max_length=100, help_text=_( u'Used to access this instance, the "slug" is a short label ' + 'containing only letters, numbers, underscore or dash top.'), editable=False) description = RichTextField( _('Description'), config_name='complete', blank=True, help_text=_("In this field you can describe your content, " "add all needed related information, and " "format the result using the toolbar.")) headband = models.ForeignKey(CustomImageModel, models.SET_NULL, blank=True, null=True, verbose_name=_('Headband')) color = models.CharField( _('Background color'), max_length=10, blank=True, null=True, help_text=_("The background color for your channel. " "You can use the format #. i.e.: #ff0000 for red")) style = models.TextField( _('Extra style'), null=True, blank=True, help_text=_("The style will be added to your channel to show it")) owners = models.ManyToManyField( User, related_name='owners_channels', verbose_name=_('Owners'), blank=True) users = models.ManyToManyField( User, related_name='users_channels', verbose_name=_('Users'), blank=True) visible = models.BooleanField( verbose_name=_('Visible'), help_text=_( u'If checked, the channel appear in a list of available ' + 'channels on the platform.'), default=False) class Meta: ordering = ['title'] verbose_name = _('Channel') verbose_name_plural = _('Channels') def __str__(self): return "%s" % (self.title) def get_absolute_url(self): return reverse('channel', args=[str(self.slug)]) def get_all_theme(self): list_theme = {} for theme in self.themes.filter(parentId=None): list_theme["%s" % theme.id] = { "title": "%s" % theme.title, "slug": "%s" % theme.slug, "url": "%s" % theme.get_absolute_url(), "child": theme.get_all_children_tree() } return list_theme def get_all_theme_json(self): return json.dumps(self.get_all_theme()) def save(self, *args, **kwargs): self.slug = slugify(self.title) super(Channel, self).save(*args, **kwargs)
class Article(models.Model): title = models.CharField(max_length=100) slug = models.SlugField() body = models.TextField() date = models.DateTimeField(auto_now_add=True)
class Migration(migrations.Migration): initial = True dependencies = [ ('auth', '0011_update_proxy_permissions'), ] operations = [ migrations.CreateModel( name='Cart', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('cart_id', models.CharField(blank=True, max_length=200)), ], options={ 'verbose_name': 'cart', 'verbose_name_plural': 'carts', 'ordering': ('cart_id', ), }, ), migrations.CreateModel( name='Category', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=300, unique=True)), ('description', models.TextField(blank=True, null=True)), ('slug', models.SlugField(max_length=200, unique=True)), ], options={ 'verbose_name': 'category', 'verbose_name_plural': 'categories', 'ordering': ('name', ), }, ), migrations.CreateModel( name='Product', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=300, unique=True)), ('price', models.DecimalField(decimal_places=0, max_digits=10)), ('sold', models.IntegerField(blank=True, null=True)), ('image', models.ImageField(blank=True, upload_to='image')), ('description', models.TextField(blank=True, null=True)), ('slug', models.SlugField(max_length=200, unique=True)), ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hyuzi.Category')), ], options={ 'verbose_name': 'product', 'verbose_name_plural': 'products', 'ordering': ('name', ), }, ), migrations.CreateModel( name='CartItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField(blank=True)), ('active', models.BooleanField(default=True)), ('cart', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hyuzi.Cart')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hyuzi.Product')), ], options={ 'db_table': 'CartItem', }, ), migrations.CreateModel( name='User', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('email', models.EmailField(max_length=255, unique=True)), ('nickname', models.CharField(max_length=100, unique=True)), ('username', models.CharField(blank=True, max_length=100, unique=True)), ('address', models.CharField(blank=True, max_length=300, unique=True)), ('phone', models.CharField(blank=True, max_length=11, unique=True)), ('is_active', models.BooleanField(default=True)), ('is_admin', models.BooleanField(default=False)), ('is_superuser', models.BooleanField(default=False)), ('is_staff', models.BooleanField(default=False)), ('date_joined', models.DateTimeField(auto_now_add=True)), ('groups', models.ManyToManyField( blank=True, help_text= 'The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), ('user_permissions', models.ManyToManyField( blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ 'abstract': False, }, managers=[ ('objects', hyuzi.models.UserManager()), ], ), ]
class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='WebUser', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('username', models.CharField(max_length=50, unique=True, verbose_name='用户名')), ('fullname', models.CharField(max_length=50, verbose_name='全名')), ('usertype', models.CharField(choices=[('A', '系统管理员'), ('M', '会议管理员'), ('R', '审查人'), ('D', '设计单位')], default='M', max_length=1)), ('is_active', models.BooleanField(default=True)), ], options={ 'verbose_name': '用户', 'verbose_name_plural': '用户', }, ), migrations.CreateModel( name='Comment', fields=[ ('ID', models.URLField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('sub_time', models.DateTimeField(verbose_name='提交时间')), ('last_update_time', models.DateTimeField(auto_now=True, verbose_name='最后更新时间')), ('content', models.TextField(verbose_name='内容')), ], options={ 'verbose_name': '专家意见', 'verbose_name_plural': '专家意见', }, ), migrations.CreateModel( name='Conference', fields=[ ('ID', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=100, verbose_name='会议名称')), ('equipment_stage', models.CharField(blank=True, choices=[('论证阶段', '论证阶段'), ('方案阶段', '方案阶段'), ('工程研制阶段', '工程研制阶段'), ('设计定型阶段', '设计定型阶段'), ('生产定型阶段', '生产定型阶段')], max_length=20, verbose_name='研制阶段')), ('review_name', models.CharField(max_length=100, verbose_name='评审名称')), ('begin_date', models.DateTimeField(verbose_name='开始时间')), ('end_date', models.DateTimeField(verbose_name='结束时间')), ('address', models.CharField(max_length=100, verbose_name='会议地址')), ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('last_update_time', models.DateTimeField(auto_now=True, verbose_name='最后更新时间')), ('profile', models.TextField(blank=True, verbose_name='会议须知')), ], options={ 'verbose_name': '审查/评审会议', 'verbose_name_plural': '审查/评审会议', }, ), migrations.CreateModel( name='ConferenceGroupMember', fields=[ ('slug', models.SlugField(primary_key=True, serialize=False, verbose_name='ID')), ('role', models.CharField(blank=True, choices=[('M', '组长'), ('V', '副组长'), ('E', '成员')], max_length=32, verbose_name='职位')), ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='group_set', to='review_conference.Conference', verbose_name='审查/评审会议')), ], ), migrations.CreateModel( name='Document', fields=[ ('ID', models.URLField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=100, verbose_name='题目')), ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('last_update_time', models.DateTimeField(auto_now=True, verbose_name='最后更新时间')), ('memo', models.TextField(blank=True, verbose_name='备注')), ('file', models.FileField(blank=True, upload_to=review_conference.models.user_directory_path, verbose_name='文件')), ], options={ 'verbose_name': '技术文件', 'verbose_name_plural': '技术文件', }, ), migrations.CreateModel( name='Equipment', fields=[ ('ID', models.URLField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=100, verbose_name='名称')), ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), ('last_update_time', models.DateTimeField(auto_now=True, verbose_name='最后更新时间')), ('memo', models.TextField(blank=True, verbose_name='备注')), ], options={ 'verbose_name': '技术设备', 'verbose_name_plural': '技术设备', }, ), migrations.CreateModel( name='ReviewGroup', fields=[ ('ID', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=32, verbose_name='名称')), ], options={ 'verbose_name': '评审组', 'verbose_name_plural': '评审组', }, ), migrations.CreateModel( name='Summary', fields=[ ('ID', models.URLField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, verbose_name='ID')), ('sub_time', models.DateTimeField(verbose_name='提交时间')), ('last_update_time', models.DateTimeField(auto_now=True, verbose_name='最后更新时间')), ('content', models.TextField(verbose_name='内容')), ('conference', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.Conference', verbose_name='会议')), ('equipment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.Equipment', verbose_name='技术设备')), ], options={ 'verbose_name': '评审意见', 'verbose_name_plural': '评审意见', }, ), migrations.CreateModel( name='ConferenceManager', fields=[ ('webuser_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), ('gender', models.CharField(blank=True, choices=[('男', '男'), ('女', '女')], max_length=4, verbose_name='性别')), ('organization', models.CharField(blank=True, max_length=50, verbose_name='工作单位')), ('department', models.CharField(blank=True, max_length=50, verbose_name='部门')), ('title', models.CharField(blank=True, max_length=20, verbose_name='职务/职称')), ('phone', models.CharField(blank=True, max_length=13, verbose_name='电话')), ('memo', models.TextField(blank=True, verbose_name='备注')), ], options={ 'verbose_name': '会议管理员', 'verbose_name_plural': '会议管理员', }, bases=('review_conference.webuser',), ), migrations.CreateModel( name='DesignOrganization', fields=[ ('webuser_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), ('shortname', models.CharField(blank=True, max_length=50, verbose_name='简称')), ('address', models.CharField(blank=True, max_length=100, verbose_name='单位地址')), ('contactor', models.CharField(blank=True, max_length=20, verbose_name='联系人')), ('phone', models.CharField(blank=True, max_length=13, verbose_name='联系电话')), ('profile', models.TextField(blank=True, verbose_name='简介')), ], options={ 'verbose_name': '研制单位', 'verbose_name_plural': '研制单位', }, bases=('review_conference.webuser',), ), migrations.CreateModel( name='Reviewer', fields=[ ('webuser_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), ('gender', models.CharField(blank=True, choices=[('男', '男'), ('女', '女')], max_length=4, verbose_name='性别')), ('type', models.CharField(blank=True, choices=[('主管机关', '主管机关'), ('军事代表', '军事代表'), ('承制单位', '承制单位'), ('承试单位', '承试单位'), ('使用部队', '使用部队')], max_length=10, verbose_name='类别')), ('organization', models.CharField(blank=True, max_length=50, verbose_name='工作单位')), ('department', models.CharField(blank=True, max_length=50, verbose_name='部门')), ('title', models.CharField(blank=True, max_length=20, verbose_name='职务/职称')), ('phone', models.CharField(blank=True, max_length=13, verbose_name='电话')), ('memo', models.TextField(blank=True, verbose_name='备注')), ], options={ 'verbose_name': '会议代表', 'verbose_name_plural': '会议代表', }, bases=('review_conference.webuser',), ), migrations.CreateModel( name='WebAdmin', fields=[ ('webuser_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL)), ('gender', models.CharField(blank=True, choices=[('男', '男'), ('女', '女')], max_length=4, verbose_name='性别')), ('organization', models.CharField(blank=True, max_length=50, verbose_name='工作单位')), ('department', models.CharField(blank=True, max_length=50, verbose_name='部门')), ('title', models.CharField(blank=True, max_length=20, verbose_name='职务/职称')), ('phone', models.CharField(blank=True, max_length=13, verbose_name='电话')), ('memo', models.TextField(blank=True, verbose_name='备注')), ], options={ 'verbose_name': '系统管理员', 'verbose_name_plural': '系统管理员', }, bases=('review_conference.webuser',), ), migrations.AddField( model_name='summary', name='reviewer', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='评审专家'), ), migrations.AddField( model_name='document', name='equipment', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='document_of_equipment', to='review_conference.Equipment', verbose_name='技术设备'), ), migrations.AddField( model_name='conferencegroupmember', name='group', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='member_set', to='review_conference.ReviewGroup', verbose_name='评审组'), ), migrations.AddField( model_name='conference', name='documents', field=models.ManyToManyField(blank=True, related_name='document_of', to='review_conference.Document', verbose_name='技术文件'), ), migrations.AddField( model_name='conference', name='equipments', field=models.ManyToManyField(blank=True, related_name='equipment_of', to='review_conference.Equipment', verbose_name='技术设备'), ), migrations.AddField( model_name='conference', name='groups', field=models.ManyToManyField(blank=True, related_name='group_of', to='review_conference.ReviewGroup', verbose_name='评审组'), ), migrations.AddField( model_name='comment', name='conference', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.Conference', verbose_name='会议'), ), migrations.AddField( model_name='comment', name='equipment', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.Equipment', verbose_name='技术设备'), ), migrations.AddField( model_name='comment', name='reviewer', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='评审专家'), ), migrations.AddField( model_name='equipment', name='organization', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.DesignOrganization'), ), migrations.AddField( model_name='document', name='organization', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='document_of_organization', to='review_conference.DesignOrganization', verbose_name='设计单位'), ), migrations.AddField( model_name='conferencegroupmember', name='member', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='review_conference.Reviewer', verbose_name='成员'), ), migrations.AddField( model_name='conference', name='creator', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='conference_creator', to='review_conference.ConferenceManager', verbose_name='创建人'), ), migrations.AddField( model_name='conference', name='last_updater', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='conference_updater', to='review_conference.ConferenceManager', verbose_name='最后更新人'), ), migrations.AddField( model_name='conference', name='managers', field=models.ManyToManyField(blank=True, related_name='manager_of', to='review_conference.ConferenceManager', verbose_name='会务组'), ), migrations.AddField( model_name='conference', name='reviewers', field=models.ManyToManyField(blank=True, related_name='reviewer_of', to='review_conference.Reviewer', verbose_name='会议代表'), ), ]
class BaseDataMart(with_metaclass(BaseDataMartMetaclass, MPTTModelSignalSenderMixin, MPTTModel, PolymorphicModel)): """ ENG: The data marts for a enterprise data warehouse. RUS: Витрина данных для MDM – системы (корпоративного хранилища), Системы управления мастер-данными (MDM – Master Data Management) применяются для согласования данных различных информационных систем и создания целостного представления о клиентах, поставщиках, партнерах, продуктах, услугах или учетных записях. """ ALL_ACTIVE_TERMS_COUNT_CACHE_KEY = 'dm_act_t_cnt' ALL_ACTIVE_TERMS_IDS_CACHE_KEY = 'dm_act_t_ids' ALL_ACTIVE_TERMS_CACHE_TIMEOUT = edw_settings.CACHE_DURATIONS['data_mart_all_active_terms'] CHILDREN_BUFFER_CACHE_KEY = 'dm_ch_bf' CHILDREN_BUFFER_CACHE_SIZE = edw_settings.CACHE_BUFFERS_SIZES['data_mart_children'] CHILDREN_CACHE_KEY_PATTERN = '{parent_id}:chld' CHILDREN_CACHE_TIMEOUT = edw_settings.CACHE_DURATIONS['data_mart_children'] # таймаут для кеширования при валидации, необходим при оптимазации старта сервера в несколько потоков VALIDATE_TERM_MODEL_CACHE_TIMEOUT = edw_settings.CACHE_DURATIONS['data_mart_validate_term_model'] messages = { 'delete_restriction': _('Delete restriction'), 'change_parent_restriction': _('Change parent restriction'), 'change_slug_restriction': _('Change slug restriction'), 'has_child_restriction': _('Has child restriction'), 'change_terms_restriction': _('Change terms restriction'), 'parent_not_active': _('Parent node not active') } ENTITIES_ORDER_BY_CREATED_AT_DESC = '-created_at' ENTITIES_VIEW_COMPONENT_LIST = 'list' SYSTEM_FLAGS = { 0: ('delete_restriction', messages['delete_restriction']), 1: ('change_parent_restriction', messages['change_parent_restriction']), 2: ('change_slug_restriction', messages['change_slug_restriction']), 3: ('has_child_restriction', messages['has_child_restriction']), 4: ('change_terms_restriction', messages['change_terms_restriction']) } TERMS_M2M_VERBOSE_NAME = _("Data mart term") TERMS_M2M_VERBOSE_NAME_PLURAL = _("Data marts terms") parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True, verbose_name=_('Parent')) name = models.CharField(verbose_name=_('Name'), max_length=255) slug = models.SlugField(_("Datamart slug"), help_text=_("Used for URLs, auto-generated from name if blank.")) path = models.CharField(verbose_name=_("Path"), max_length=255, db_index=True, editable=False, unique=True) terms = deferred.ManyToManyField('BaseTerm', related_name='+', verbose_name=_('Terms'), blank=True) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at")) updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated at")) ordering = models.CharField(verbose_name=_('Ordering'), max_length=255, default=ENTITIES_ORDER_BY_CREATED_AT_DESC, help_text=_('Default data mart entities ordering mode.')) view_component = models.CharField(verbose_name=_('View component'), max_length=255, default=ENTITIES_VIEW_COMPONENT_LIST, help_text=_('Default data mart entities view component.')) limit = models.IntegerField(verbose_name=_('Limit'), null=True, blank=True, validators=[MinValueValidator(1)], help_text=_('Entities per page. Leave empty for default (by default: {}).').format( edw_settings.REST_PAGINATION['entity_default_limit'])) view_class = models.CharField(verbose_name=_('View Class'), max_length=255, null=True, blank=True, help_text=_('Space delimited class attribute, specifies one or more classnames for an data mart.')) description = models.TextField(verbose_name=_('Description'), null=True, blank=True) active = models.BooleanField(default=True, verbose_name=_("Active"), db_index=True, help_text=_("Is this data mart active.")) system_flags = BitField(flags=SYSTEM_FLAGS, verbose_name=_('system flags'), null=True, default=None) _relations = deferred.ManyToManyField('BaseTerm', through=DataMartRelationModel, through_fields=('data_mart', 'term')) objects = BaseDataMartManager() # Whether the node type allows to have children. can_have_children = True class Meta: """ RUS: Метакласс для определения специальных параметров модели. """ abstract = True verbose_name = _("Data mart") verbose_name_plural = _("Data marts") class MPTTMeta: """ RUS: Метакласс Django MPTT для определения параметров дерева. """ order_insertion_by = ['created_at'] class RESTMeta: """ RUS: Метакласс для определения параметров сериалайзера. """ lookup_fields = ('id', 'slug') def __str__(self): # Возвращаем наименование витрины данных. return self.name def __lt__(self, other): """ RUS: Сравнивает узлы витрины данных для организации сортировки согласно структуре дерева. """ tree_opts = self._mptt_meta self_tree_id, self_tree_left = getattr(self, tree_opts.tree_id_attr), getattr(self, tree_opts.left_attr) other_tree_id, other_tree_left = getattr(other, tree_opts.tree_id_attr), getattr(other, tree_opts.left_attr) if self_tree_id == other_tree_id: return self_tree_left < other_tree_left else: return self_tree_id < other_tree_id def __eq__(self, other): if not isinstance(other, type(self)): # Delegate comparison to the other instance's __eq__. return NotImplemented return self.pk == other.pk def data_mart_type(self): """ ENG: Returns the polymorphic type of the object. RUS: Возвращает полиморфный тип объекта """ return force_text(self.polymorphic_ctype) data_mart_type.short_description = _("Data mart type") @property def data_mart_model(self): """ ENG: Returns the polymorphic model name of the object's class. RUS: Возвращает полиморфную модель имени класса объекта """ return self.polymorphic_ctype.model def get_absolute_url(self, request=None, format=None): """ ENG: Hook for returning the canonical Django URL of this object. RUS: Вычисляет URL объекта, который должен быть реализован подклассом. """ msg = "Method get_absolute_url() must be implemented by subclass: `{}`" raise NotImplementedError(msg.format(self.__class__.__name__)) @classmethod def get_all_subclasses(cls): """ ENG: Helper function to get all the subclasses of a class. RUS: Вспомогательная функция для получения всех подклассов текущего класса. """ for subclass in cls.__subclasses__(): for subsubclass in subclass.get_all_subclasses(): yield subsubclass yield subclass @cached_property def ancestors_list(self): """ ENG: Creates a QuerySet containing the ancestors of the model instance (root ancestor first, immediate parent last). RUS: Получает список родительских элементов (предков) указанного экземпляра, включая сам экземпляр модели. """ return list(self.parent.get_ancestors(include_self=True)) if self.parent else [] def clean(self, *args, **kwargs): """ ENG: Validate the model as a whole. RUS: Проверка всей модели на уникальность. Первичный ключ должен быть равен id объекта. """ model_class = self.__class__ try: origin = model_class._default_manager.get(pk=self.id) except model_class.DoesNotExist: origin = None if self.system_flags: if origin is not None: if self.system_flags.change_slug_restriction and origin.slug != self.slug: raise ValidationError(self.messages['change_slug_restriction']) if self.system_flags.change_parent_restriction and origin.parent_id != self.parent_id: raise ValidationError(self.messages['change_parent_restriction']) if self.parent_id is not None and self.parent.system_flags.has_child_restriction: if origin is None or origin.parent_id != self.parent_id: raise ValidationError(self.messages['has_child_restriction']) return super(BaseDataMart, self).clean(*args, **kwargs) def need_terms_validation(self, origin, **kwargs): """ RUS: Тест на необходимость проведения валидации терминов. """ return origin is None def validate_terms(self, origin, **kwargs): """ RUS: Валидация терминов. """ pass def _make_path(self, items): make_path(self, items) def save(self, *args, **kwargs): force_update = kwargs.get('force_update', False) if not force_update: model_class = self.__class__ ancestors = self.ancestors_list # determine whether this instance is already in the db try: origin = model_class._default_manager.get(pk=self.id) except model_class.DoesNotExist: origin = None if not origin or origin.view_class != self.view_class: self.view_class = ' '.join([x.lower() for x in self.view_class.split()]) if self.view_class else None self._make_path(ancestors + [self]) try: with transaction.atomic(): result = super(BaseDataMart, self).save(*args, **kwargs) except IntegrityError as e: if model_class._default_manager.exclude(pk=self.pk).filter(path=self.path).exists(): self.slug = get_unique_slug(self.slug, self.id) self._make_path(ancestors + [self]) result = super(BaseDataMart, self).save(*args, **kwargs) else: raise e if not origin or origin.active != self.active: if self.active: update_id_list = list(self.get_family().values_list('id', flat=True)) else: update_id_list = list(self.get_descendants(include_self=False).values_list('id', flat=True)) model_class._default_manager.filter(id__in=update_id_list).update(active=self.active) force_validate_terms = kwargs.get('force_validate_terms', False) validation_context = {} if force_validate_terms or self.need_terms_validation(origin, context=validation_context): if hasattr(self, '_valid_pk_set'): del self._valid_pk_set self._during_terms_validation = True self.validate_terms(origin, context=validation_context) del self._during_terms_validation else: result = super(BaseDataMart, self).save(*args, **kwargs) return result def delete(self): """ RUS: Удаляет объекты, если не проставлен системный флаг с ограничением на удаление. """ if not self.system_flags.delete_restriction: super(BaseDataMart, self).delete() def hard_delete(self): """ RUS: Принудительное удаление объекта из витрины данных. """ super(BaseDataMart, self).delete() def move_to(self, target, position='first-child'): """ RUS: Перемещает объект по дереву витрины данных с возможностью изменения родителя или добавления потомка, если непроставлен системный флаг на ограничение. """ if position in ('left', 'right'): if target.parent_id != self.parent_id: if self.system_flags.change_parent_restriction: raise InvalidMove(self.messages['change_parent_restriction']) if target.parent_id is not None: if target.parent.system_flags.has_child_restriction: raise InvalidMove(self.messages['has_child_restriction']) if self.active and not target.parent.active: raise InvalidMove(self.messages['parent_not_active']) elif position in ('first-child', 'last-child'): if target.id != self.parent_id: if self.system_flags.change_parent_restriction: raise InvalidMove(self.messages['change_parent_restriction']) if target.system_flags.has_child_restriction: raise InvalidMove(self.messages['has_child_restriction']) if not target.active and self.active: raise InvalidMove(self.messages['parent_not_active']) super(BaseDataMart, self).move_to(target, position) def get_children_cache_key(self): """ RUS: Получает ключ кэша для объекта запроса, содержащего дочерние элементы. """ return self.CHILDREN_CACHE_KEY_PATTERN.format( parent_id=self.id ) @add_cache_key(get_children_cache_key) def get_children(self): """ RUS: Возвращает объект запроса, содержащий дочерние элементы, хранящиеся в кэше. """ return super(BaseDataMart, self).get_children() @staticmethod def get_children_buffer(): """ RUS: Помещает в буффер результат запроса, содержащий дочерние элементы. """ return RingBuffer.factory(BaseDataMart.CHILDREN_BUFFER_CACHE_KEY, max_size=BaseDataMart.CHILDREN_BUFFER_CACHE_SIZE) @staticmethod def clear_children_buffer(): """ RUS: Очищает из буффера результат запроса, содержащий дочерние элементы. """ buf = BaseDataMart.get_children_buffer() keys = buf.get_all() buf.clear() cache.delete_many(keys) @staticmethod def get_all_active_terms_ids(): """ RUS: Возвращает id всех активных терминов из кэша и добавляет в кэш, если их там нет. """ key = BaseDataMart.ALL_ACTIVE_TERMS_IDS_CACHE_KEY result = cache.get(key, None) if result is None: active_terms_ids = DataMartModel.terms.through.objects.distinct().filter(term__active=True).values_list( 'term__id', flat=True) result = list(TermModel.decompress(active_terms_ids, fix_it=False).keys()) cache.set(key, result, BaseDataMart.ALL_ACTIVE_TERMS_CACHE_TIMEOUT) return result @staticmethod def get_all_active_terms_count(): """ RUS: Возвращает id всех активных терминов из кэша с вычислением их количества и добавляет в кэш, если их там нет. """ key = BaseDataMart.ALL_ACTIVE_TERMS_COUNT_CACHE_KEY result = cache.get(key, None) if result is None: terms_info = DataMartModel.objects.distinct().filter(terms__active=True).annotate( num=models.Count('terms__id')).values('id', 'num') result = {} for obj in terms_info: result[obj['id']] = obj['num'] cache.set(key, result, BaseDataMart.ALL_ACTIVE_TERMS_CACHE_TIMEOUT) return result @cached_property def active_terms_ids(self): """ RUS: Возвращает кэш id всех активных терминов. """ return list(self.terms.active().values_list('id', flat=True)) @staticmethod def get_base_entity_model(): """ RUS: Возвращает базовую модель объекта (сущности). """ base_entity_model = getattr(DataMartModel, "_base_entity_model_cache", None) if base_entity_model is None: from .entity import EntityModel base_entity_model = EntityModel.materialized DataMartModel._base_entity_model_cache = base_entity_model return base_entity_model @staticmethod def get_entities_model(terms_ids): """ RUS: Создает модель сущности со связанными с ней терминами, унаследованную от базовой модели сущности. """ base_entity_model = DataMartModel.get_base_entity_model() entities_types = dict([(term.id, term) for term in base_entity_model.get_entities_types().values()]) entities_types_terms_ids = entities_types.keys() crossing_terms_ids = list(set(entities_types_terms_ids) & set(terms_ids)) try: return entities_types[crossing_terms_ids[0]]._entity_model_class except IndexError: return base_entity_model @cached_property def is_subjective(self): """ RUS: Возвращает запрос со связанными субъектами сущности. ENG: Returns a QuerySet with entity objects. """ return self.relations.all().exists() @cached_property def entities_model(self): """ ENG: Return Data Mart entities collection Model. RUS: Возвращает витрины данных модели сущности с активными терминами. """ return self.get_entities_model(self.active_terms_ids) def get_summary_extra(self, context): """ RUS: Возвращает дополнительные данные для итогового сериалайзера. ENG: Return extra data for summary serializer. """ return None def get_tree_extra(self): """ ENG: Return extra data for tree serializer. RUS: Возвращает дополнительные данные для дерева сериалайзера. """ return None @classmethod def validate_term_model(cls): """ RUS: Проверка соответствия модели терминов. """ pass @staticmethod def separate_relations(relations): """ ENG: Separate data mart relations into forward and backward (reverse) relations ids. RUS: Разделяет связи объектов витрины данных на прямые и обратные связи с созданием реляционного ключа. """ rel_f_ids, rel_r_ids = [], [] for relation in relations: if relation.direction == 'f': rel_f_ids.append(relation.term_id) elif relation.direction == 'r': rel_r_ids.append(relation.term_id) else: rel_f_ids.append(relation.term_id) rel_r_ids.append(relation.term_id) return rel_f_ids, rel_r_ids @staticmethod def get_relations_subjects(relations): """ ENG: Get data mart relations subjects. RUS: Получает список связанных субъектов витрин данных. """ return {relation.term_id: list( relation.subjects.values_list('id', flat=True) ) for relation in relations} def get_permissions_from_request(self, request): """ Get data mart permissions from request. """ result = { 'can_add': False, 'can_change': False, 'can_delete': False, 'has_owner': False } user = request.user if user.is_authenticated() and user.is_active: if user.is_superuser or not DataMartPermissionModel.objects.filter(data_mart_id=self.id).exists(): result = { 'can_add': True, 'can_change': True, 'can_delete': True, 'has_owner': False } else: try: result = DataMartPermissionModel.objects.values('can_add', 'can_change', 'can_delete').get( customer__user_id=user.id, data_mart_id=self.id) except DataMartPermissionModel.DoesNotExist: pass result['has_owner'] = True return result
class Talk(StatusModel): STATUS = Choices('active', 'draft') name = models.CharField(u'Название', max_length=1024) speaker = models.ForeignKey('Speaker', verbose_name=u'Докладчик', related_name='talks') event = models.ForeignKey('Event', verbose_name=u'Событие', related_name='talks') slug = models.SlugField(u'Код') description = models.TextField(u'Описание', blank=True) presentation = models.URLField(u'Адрес презентации', blank=True) presentation_data = PickledObjectField(u'Meta-данные презентации', editable=True, blank=True) video = models.URLField(u'Адрес видео', blank=True) video_data = PickledObjectField(u'Meta-данные видео', blank=True) position = models.SmallIntegerField( u'Порядок', help_text=u'Порядок выступления на событии', default=0) start_time = models.TimeField(u'Время начала', blank=True, null=True) end_time = models.TimeField(u'Время окончания', blank=True, null=True) objects = TalkManager() original_presentation = None original_video = None def __init__(self, *args, **kwargs): super(Talk, self).__init__(*args, **kwargs) self.original_presentation = self.presentation self.original_video = self.video def __str__(self): return self.name @permalink def get_absolute_url(self): return 'talk', [self.event.number, self.slug] def set_embedly_data(self, field_name): original_field_value = getattr(self, 'original_{0}'.format(field_name)) new_field_value = getattr(self, field_name) if new_field_value != original_field_value: data_field_name = '{0}_data'.format(field_name) if new_field_value: embedly_key = getattr(settings, 'EMBEDLY_KEY') if embedly_key: client = Embedly(embedly_key) setattr(self, data_field_name, client.oembed(new_field_value)._data) else: setattr(self, data_field_name, "") setattr(self, 'original_{0}'.format(field_name), new_field_value) def save(self, *args, **kwargs): self.set_embedly_data('presentation') self.set_embedly_data('video') super(Talk, self).save(*args, **kwargs) # TODO: Add to talks normal timing def get_time_start(self): if self.start_time: return self.start_time return self.event.date + datetime.timedelta(minutes=40 * self.position) def get_time_end(self): if self.end_time: return self.end_time return self.event.date + datetime.timedelta(minutes=40 * (self.position + 1)) class Meta: verbose_name = u'Выступление' verbose_name_plural = u'Выступления' ordering = ( '-event__number', 'position', )
class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Inbox', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField()), ('created', models.DateTimeField(auto_now_add=True)), ], ), migrations.CreateModel( name='UserPhoto', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('photo', models.URLField()), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='userphoto_user', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Setting', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('maximum_distance', models.IntegerField()), ('gender', models.CharField(max_length=256)), ('age_range', models.IntegerField()), ('show_me_on_searches', models.BooleanField()), ('new_matches_notification', models.BooleanField()), ('message_notification', models.BooleanField()), ('message_likes_notification', models.BooleanField()), ('super_like_notification', models.BooleanField()), ('in_app_vibrations', models.BooleanField()), ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='setting_user', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Profile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('bio', models.TextField()), ('school', models.TextField()), ('date_of_birth', models.DateField()), ('created', models.DateField(auto_now_add=True)), ('modified', models.DateField(auto_now=True)), ('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='profile_user', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Match', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created', models.DateTimeField(auto_now_add=True)), ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='match_owner', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='match_user', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Like', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('super_liked', models.BooleanField()), ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='like_owner', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='like_user', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='Dislike', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dislike_owner', to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dislike_user', to=settings.AUTH_USER_MODEL)), ], ), ]
class Category(models.Model): class Meta: verbose_name_plural = 'Categories' ordering = ('name', ) name = models.CharField(max_length=50) #client = models.ForeignKey('accounts.Client') #tagline = models.CharField(max_length=500, blank = True, null = True) description = models.TextField(blank=True, null=True) slug = models.SlugField(max_length=100) image = models.ImageField(upload_to='category/%Y/%m', storage=upload_storage, blank=True, null=True) sort_order = models.PositiveIntegerField(default=1) #objects = CategoryCacheManager() def save(self, *args, **kwargs): if self.id: cache.delete('categories:category:%s' % self.id) return super(Category, self).save(*args, **kwargs) def featured_products(self): from promotions.models import FeaturedProducts products = FeaturedProducts.objects.filter(category=self, type='mega_drop_down')[:2] return products def url(self): return "%s/ch/%s/" % (self.slug, self.id) def get_children(self, category, children): try: graph = CategoryGraph.objects.filter(parent=category) except CategoryGraph.DoesNotExist: return children if not graph: return children for node in graph: children.append(node.category) self.get_children(node.category, children) return children def get_all_children(self): cat = self children = [] children = self.get_children(cat, children) return children def get_parents(self, category, parents): g = CategoryGraph.objects.filter(category=category) for graph in g: parent = graph.parent if not parent: continue else: parents.append(parent) self.get_parents(parent, parents) return def get_all_parents(self): cat = self parents = [] self.get_parents(cat, parents) exists = {} unique_parents = [] for p in parents: if p.id not in exists: unique_parents.append(p) exists[p.id] = True return unique_parents def has_products(self): if self.product_set.filter(status='active').count() > 0: return True else: total = 0 for c in self.get_all_children(): total += c.product_set.filter(status='active').count() if total > 0: return True return False def __unicode__(self): return self.name #return '%s(%s)-%s' % (self.name, self.ext_id, self.client.name) def get_display_url(self): images = self.categoryimage_set.all().order_by('id') if images: display = images[0].get_display_url() else: display = '' return display def get_thumbnail_218x218(self): images = self.categoryimage_set.all().order_by('id') if images: thumb = images[0].get_thumbnail_218x218() else: thumb = '' return thumb def get_display_170x170(self): images = self.categoryimage_set.all().order_by('id') if images: disp = images[0].get_display_170x170() else: disp = '' return disp def get_thumbnail_110x110(self): images = self.categoryimage_set.all().order_by('id') if images: disp = images[0].get_thumbnail_110x110() else: disp = '' return disp def get_banner_670x342(self): images = self.categoryimage_set.all().order_by('-id') if images: banner = images[0].get_banner_670x342() else: banner = '' return banner
class Project(Model): """ Projects are permission based namespaces which generally are the top level entry point for all data. """ __core__ = True slug = models.SlugField(null=True) name = models.CharField(max_length=200) forced_color = models.CharField(max_length=6, null=True, blank=True) organization = FlexibleForeignKey('sentry.Organization') # DEPRECATED. use teams instead. team = FlexibleForeignKey('sentry.Team', null=True) teams = models.ManyToManyField( 'sentry.Team', related_name='teams', through=ProjectTeam ) public = models.BooleanField(default=False) date_added = models.DateTimeField(default=timezone.now) status = BoundedPositiveIntegerField( default=0, choices=( (ObjectStatus.VISIBLE, _('Active')), (ObjectStatus.PENDING_DELETION, _('Pending Deletion')), (ObjectStatus.DELETION_IN_PROGRESS, _('Deletion in Progress')), ), db_index=True ) # projects that were created before this field was present # will have their first_event field set to date_added first_event = models.DateTimeField(null=True) flags = BitField( flags=(('has_releases', 'This Project has sent release data'), ), default=0, null=True ) objects = ProjectManager(cache_fields=[ 'pk', 'slug', ]) platform = models.CharField(max_length=64, null=True) class Meta: app_label = 'sentry' db_table = 'sentry_project' unique_together = (('team', 'slug'), ('organization', 'slug')) __repr__ = sane_repr('team_id', 'name', 'slug') def __unicode__(self): return u'%s (%s)' % (self.name, self.slug) def next_short_id(self): from sentry.models import Counter return Counter.increment(self) def save(self, *args, **kwargs): if not self.slug: lock = locks.get('slug:project', duration=5) with TimedRetryPolicy(10)(lock.acquire): slugify_instance(self, self.name, organization=self.organization) super(Project, self).save(*args, **kwargs) else: super(Project, self).save(*args, **kwargs) def get_absolute_url(self): return absolute_uri('/{}/{}/'.format(self.organization.slug, self.slug)) def is_internal_project(self): for value in (settings.SENTRY_FRONTEND_PROJECT, settings.SENTRY_PROJECT): if six.text_type(self.id) == six.text_type(value) or six.text_type( self.slug ) == six.text_type(value): return True return False # TODO: Make these a mixin def update_option(self, *args, **kwargs): from sentry.models import ProjectOption return ProjectOption.objects.set_value(self, *args, **kwargs) def get_option(self, *args, **kwargs): from sentry.models import ProjectOption return ProjectOption.objects.get_value(self, *args, **kwargs) def delete_option(self, *args, **kwargs): from sentry.models import ProjectOption return ProjectOption.objects.unset_value(self, *args, **kwargs) @property def callsign(self): return self.slug.upper() @property def color(self): if self.forced_color is not None: return '#%s' % self.forced_color return get_hashed_color(self.callsign or self.slug) @property def member_set(self): from sentry.models import OrganizationMember return self.organization.member_set.filter( id__in=OrganizationMember.objects.filter( organizationmemberteam__is_active=True, organizationmemberteam__team=self.team, ).values('id'), user__is_active=True, ).distinct() def has_access(self, user, access=None): from sentry.models import AuthIdentity, OrganizationMember warnings.warn('Project.has_access is deprecated.', DeprecationWarning) queryset = self.member_set.filter(user=user) if access is not None: queryset = queryset.filter(type__lte=access) try: member = queryset.get() except OrganizationMember.DoesNotExist: return False try: auth_identity = AuthIdentity.objects.get( auth_provider__organization=self.organization_id, user=member.user_id, ) except AuthIdentity.DoesNotExist: return True return auth_identity.is_valid(member) def get_audit_log_data(self): return { 'id': self.id, 'slug': self.slug, 'name': self.name, 'status': self.status, 'public': self.public, } def get_full_name(self): if self.team.name not in self.name: return '%s %s' % (self.team.name, self.name) return self.name def get_notification_recipients(self, user_option): from sentry.models import UserOption alert_settings = dict( (o.user_id, int(o.value)) for o in UserOption.objects.filter( project=self, key=user_option, ) ) disabled = set(u for u, v in six.iteritems(alert_settings) if v == 0) member_set = set( self.member_set.exclude( user__in=disabled, ).values_list('user', flat=True) ) # determine members default settings members_to_check = set(u for u in member_set if u not in alert_settings) if members_to_check: disabled = set( ( uo.user_id for uo in UserOption.objects.filter( key='subscribe_by_default', user__in=members_to_check, ) if uo.value == '0' ) ) member_set = [x for x in member_set if x not in disabled] return member_set def get_mail_alert_subscribers(self): user_ids = self.get_notification_recipients('mail:alert') if not user_ids: return [] from sentry.models import User return list(User.objects.filter(id__in=user_ids)) def is_user_subscribed_to_mail_alerts(self, user): from sentry.models import UserOption is_enabled = UserOption.objects.get_value(user, 'mail:alert', project=self) if is_enabled is None: is_enabled = UserOption.objects.get_value(user, 'subscribe_by_default', '1') == '1' else: is_enabled = bool(is_enabled) return is_enabled def transfer_to(self, team): from sentry.models import ProjectTeam, ReleaseProject organization = team.organization from_team_id = self.team_id # We only need to delete ReleaseProjects when moving to a different # Organization. Releases are bound to Organization, so it's not realistic # to keep this link unless we say, copied all Releases as well. if self.organization_id != organization.id: ReleaseProject.objects.filter( project_id=self.id, ).delete() self.organization = organization self.team = team try: with transaction.atomic(): self.update( organization=organization, team=team, ) except IntegrityError: slugify_instance(self, self.name, organization=organization) self.update( slug=self.slug, organization=organization, team=team, ) ProjectTeam.objects.filter(project=self, team_id=from_team_id).update(team=team) def add_team(self, team): try: with transaction.atomic(): ProjectTeam.objects.create(project=self, team=team) except IntegrityError: return False else: return True def remove_team(self, team): ProjectTeam.objects.filter( project=self, team=team, ).delete() def get_security_token(self): lock = locks.get(self.get_lock_key(), duration=5) with TimedRetryPolicy(10)(lock.acquire): security_token = self.get_option('sentry:token', None) if security_token is None: security_token = uuid1().hex self.update_option('sentry:token', security_token) return security_token def get_lock_key(self): return 'project_token:%s' % self.id
class Migration(migrations.Migration): dependencies = [ ('common', '0001_initial'), ] operations = [ migrations.AlterField( model_name='repository', name='categories', field=models.ManyToManyField( help_text= 'Categories for approaching repositories with the same purpose', to='common.RepositoryCategory'), ), migrations.AlterField( model_name='repository', name='description', field=models.TextField(blank=True, help_text='Tell what your bot do!', verbose_name='description'), ), migrations.AlterField( model_name='repository', name='is_private', field=models.BooleanField( default=False, help_text= 'Your repository can be private, only you can see and use, or can be public and all community can see and use.', verbose_name='private'), ), migrations.AlterField( model_name='repository', name='language', field=models.CharField( choices=[('en', 'English'), ('de', 'German'), ('es', 'Spanish'), ('pt', 'Portuguese'), ('fr', 'French'), ('it', 'Italian'), ('nl', 'Dutch')], help_text= "Repository's examples language. The examples can be translated to other languages.", max_length=2, verbose_name='language'), ), migrations.AlterField( model_name='repository', name='name', field=models.CharField(help_text='Repository display name', max_length=64, verbose_name='name'), ), migrations.AlterField( model_name='repository', name='slug', field=models.SlugField( help_text='Easy way to found and share repositories', max_length=32, unique=True, verbose_name='slug'), ), migrations.AlterField( model_name='repositoryexample', name='intent', field=models.CharField(blank=True, help_text='Example intent reference', max_length=64, verbose_name='intent'), ), migrations.AlterField( model_name='repositoryexample', name='text', field=models.TextField(help_text='Example text', verbose_name='text'), ), migrations.AlterField( model_name='repositoryexampleentity', name='end', field=models.PositiveIntegerField( help_text='End index of entity value in example text', verbose_name='end'), ), migrations.AlterField( model_name='repositoryexampleentity', name='entity', field=models.CharField(help_text='Entity name', max_length=64, verbose_name='entity'), ), migrations.AlterField( model_name='repositoryexampleentity', name='repository_example', field=models.ForeignKey( editable=False, help_text='Example object', on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='common.RepositoryExample'), ), migrations.AlterField( model_name='repositoryexampleentity', name='start', field=models.PositiveIntegerField( help_text='Start index of entity value in example text', verbose_name='start'), ), migrations.AlterField( model_name='repositorytranslatedexample', name='language', field=models.CharField(choices=[ ('en', 'English'), ('de', 'German'), ('es', 'Spanish'), ('pt', 'Portuguese'), ('fr', 'French'), ('it', 'Italian'), ('nl', 'Dutch') ], help_text='Translation language', max_length=2, verbose_name='language'), ), migrations.AlterField( model_name='repositorytranslatedexample', name='original_example', field=models.ForeignKey( editable=False, help_text='Example object', on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='common.RepositoryExample'), ), migrations.AlterField( model_name='repositorytranslatedexample', name='text', field=models.TextField(help_text='Translation text', verbose_name='text'), ), migrations.AlterField( model_name='repositorytranslatedexampleentity', name='end', field=models.PositiveIntegerField( help_text='End index of entity value in example text', verbose_name='end'), ), migrations.AlterField( model_name='repositorytranslatedexampleentity', name='entity', field=models.CharField(help_text='Entity name', max_length=64, verbose_name='entity'), ), migrations.AlterField( model_name='repositorytranslatedexampleentity', name='repository_translated_example', field=models.ForeignKey( editable=False, help_text='Translated example object', on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='common.RepositoryTranslatedExample'), ), migrations.AlterField( model_name='repositorytranslatedexampleentity', name='start', field=models.PositiveIntegerField( help_text='Start index of entity value in example text', verbose_name='start'), ), ]
class Post(models.Model): DRAFT = "DRF" PUBLISHED = "PUB" BAN = "BAN" status_choices = [ (DRAFT, "draft"), (PUBLISHED, "publised"), (BAN, "ban"), ] title = models.CharField(max_length=100) creation_date = models.DateTimeField(default=timezone.now) author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) slug = models.SlugField(unique_for_date="creation_date", null=True, blank=True) commments_alow = models.BooleanField(default=True) tags = TaggableManager(blank=True) body = models.TextField(null=True, blank=True) excerpt = models.TextField(max_length=100, blank=True) body_html = models.TextField(null=True, blank=True) excerpt_html = models.TextField(blank=True, null=True, editable=False) last_accessed = models.DateTimeField(null=True, blank=True) status = models.CharField(max_length=3, choices=status_choices, default=DRAFT) #At first we should declare the original model maneger that is "objects" by default objects = models.Manager() # Then instantiated the custom manager to connect the model to its manager publish = Post_published_Manager() # cause the 'detail' view url captures the year,slug,month and day , we should declare the 'kwargs' argument to definite these parts in url def get_absolute_url(self): return reverse('chat:details', kwargs={ 'slug': self.slug, 'year': self.creation_date.year, 'month': self.creation_date.month, 'day': self.creation_date.day, }) def __str__(self): return self.title # def publish(self): # self.creation_date =timezone.now() # self.save() """ To save the marked down texts in 'body_html' field, we override the 'save' method to convert raw text to markdown text (in this case HTML). Every time that we override the save method ,we should confident that we pass '*args' and '**kwargs' arguments in the function defenition and super object. it ensure that this method captured its own arguments and every posibillity that may added to this method in future . """ def save(self, *args, **kwargs): if self.body: self.body_html = markdown(self.body) if self.excerpt: self.excerpt_html = markdown(self.excerpt) self.slug = slugify(self.title) super().save(*args, **kwargs)
class Migration(migrations.Migration): dependencies = [ ('auth', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Event', fields=[ ('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')), ('name', models.CharField(verbose_name='Name', max_length=64)), ('about', models.TextField(verbose_name='About', null=True)), ('is_active', models.BooleanField(verbose_name='Activated', default=False)), ('urlslug', models.SlugField(verbose_name='URL-slug', unique=True)), ('externalurl', models.URLField(verbose_name='External website', null=True)), ('startdatetime', models.DateTimeField(verbose_name='Start time', help_text='YYYY-MM-DD HH:MM')), ('enddatetime', models.DateTimeField(verbose_name='End time', help_text='YYYY-MM-DD HH:MM')), ], options={ 'verbose_name': 'Event', 'verbose_name_plural': 'Events', }, bases=(models.Model, ), ), migrations.CreateModel( name='Organization', fields=[ ('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')), ('name', models.CharField(verbose_name='Name', max_length=64)), ('about', models.TextField(verbose_name='About', null=True)), ('is_active', models.BooleanField(verbose_name='Activated', default=False)), ('urlslug', models.SlugField(verbose_name='URL-slug', unique=True)), ('externalurl', models.URLField(verbose_name='External website', null=True)), ('owner', models.ForeignKey(verbose_name='Owner', editable=False, to='auth.Group', null=True)), ], options={ 'verbose_name': 'Organization', 'verbose_name_plural': 'Organizations', }, bases=(models.Model, ), ), migrations.CreateModel( name='UserProfile', fields=[ ('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')), ('date_of_birth', models.DateField(null=True)), ('streetaddress', models.CharField(max_length=255, null=True)), ('country', django_countries.fields.CountryField(max_length=2, null=True)), ('postalcode', models.PositiveSmallIntegerField(null=True)), ('gender', models.CharField(max_length=6, null=True, choices=[('female', 'Female'), ('male', 'Male')])), ('phone', models.CharField(max_length=20, null=True)), ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), ], options={}, bases=(models.Model, ), ), migrations.AddField( model_name='event', name='organization', field=models.ForeignKey(verbose_name='Organization', editable=False, to='core.Organization'), preserve_default=True, ), migrations.AddField( model_name='event', name='owner', field=models.ForeignKey(verbose_name='Owner', editable=False, to='auth.Group'), preserve_default=True, ), ]
class SCOTUSMap(models.Model): user = models.ForeignKey( User, help_text="The user that owns the visualization", related_name="scotus_maps", on_delete=models.CASCADE, ) cluster_start = models.ForeignKey( OpinionCluster, help_text="The starting cluster for the visualization", related_name='visualizations_starting_here', on_delete=models.CASCADE, ) cluster_end = models.ForeignKey( OpinionCluster, help_text="The ending cluster for the visualization", related_name='visualizations_ending_here', on_delete=models.CASCADE, ) clusters = models.ManyToManyField( OpinionCluster, help_text="The clusters involved in this visualization, including the " "start and end clusters.", related_name="visualizations", blank=True, ) date_created = models.DateTimeField( help_text="The time when this item was created", auto_now_add=True, db_index=True, ) date_modified = models.DateTimeField( help_text="The last moment when the item was modified.", auto_now=True, db_index=True, ) date_published = models.DateTimeField( help_text="The moment when the visualization was first shared", db_index=True, blank=True, null=True, ) date_deleted = models.DateTimeField( help_text="The moment when the visualization was last deleted", db_index=True, blank=True, null=True, ) title = models.CharField( help_text="The title of the visualization that you're creating.", max_length=200, ) slug = models.SlugField( help_text="The URL path that the visualization will map to (the slug)", max_length=75, ) notes = models.TextField( help_text="A description to help explain the diagram, in Markdown " "format", blank=True, ) view_count = models.IntegerField( help_text="The number of times the visualization has been seen.", default=0, ) published = models.BooleanField( help_text="Whether the visualization has been shared.", default=False, ) deleted = models.BooleanField( help_text="Has a user chosen to delete this visualization?", default=False, ) generation_time = models.FloatField( help_text="The length of time it takes to generate a visuzalization, " "in seconds.", default=0, ) __original_deleted = None def __init__(self, *args, **kwargs): super(SCOTUSMap, self).__init__(*args, **kwargs) self.__original_deleted = self.deleted @property def json(self): """Returns the most recent version""" return self.json_versions.all()[0].json_data @property def referers_displayed(self): """Return good referers""" return self.referers.filter(display=True).order_by('date_created') def build_nx_digraph(self, parent_authority, visited_nodes, good_nodes, max_hops, hops_taken=0, max_nodes=70): """Recursively build a networkx graph Process is: - Work backwards through the authorities for self.cluster_end and all of its children. - For each authority, add it to a nx graph, if: - it happened after self.cluster_start - it's in the Supreme Court - we haven't exceeded max_hops - we haven't already followed this path in a longer or equal route - it is on a simple path between the beginning and end - fewer than max_nodes nodes are in the network The last point above is a complicated one. The algorithm is implemented in a depth-first fashion, so we quickly can create simple paths between the first and last node. If it were in a breadth-first algorithm, we would fan out and have to do many more queries before we learned that a line of citations was needed or not. For example, consider this network: START ├─-> A--> B--> C--> D--> END └--> E ├─-> F └--> G The only nodes that we should include are A, B, C, and D. In a depth- first approach, you do: START ├─1-> A-2-> B-3-> C-4-> D-5-> END └-8-> E ├─6-> F └-7-> G After five hops, we know that A, B, C, and D are relevant and should be kept. Compare to a breadth-first: START ├─1-> A-3-> B-4-> C-7-> D-8-> END └-2-> E ├─5-> F └-6-> G In this case, it takes eight hops to know the same thing, and in a real network, it would be many more than two or three citations from each node. This matters a great deal because the sooner we can count the number of nodes in the network, the sooner we will hit max_nodes and be able to abort if the job is too big. The other complicated part of this algorithm is keeping track of shortest routes and avoiding unneeded graph traversal. For example, it's quite possible to traverse :param parent_authority: The starting point for the recursion. At first, this will be self.cluster_end, but in recursive calls, it will be the child of the current parent. :param visited_nodes: A dict of nodes that have already been visited. :param good_nodes: A dict of nodes that have been identified as good. :param hops_taken: The number of hops taken so far, from self.cluster_end :param max_hops: The maximum degree of separation for the network. :param max_nodes: The maximum number of nodes a network can contain. """ g = networkx.DiGraph() if len(good_nodes) == 0: # Add the beginning and end. good_nodes = { self.cluster_start_id: {'shortest_path': 0}, } is_already_handled_with_shorter_path = ( parent_authority.pk in visited_nodes and visited_nodes[parent_authority.pk]['hops_taken'] < hops_taken ) has_no_more_hops_remaining = (hops_taken == max_hops) blocking_conditions = [ is_already_handled_with_shorter_path, has_no_more_hops_remaining, ] if not any(blocking_conditions): visited_nodes[parent_authority.pk] = {'hops_taken': hops_taken} hops_taken += 1 for child_authority in parent_authority.authorities.filter( docket__court='scotus', date_filed__gte=self.cluster_start.date_filed ).order_by('date_filed'): # Combine our present graph with the result of the next # recursion sub_graph = networkx.DiGraph() if child_authority == self.cluster_start: # Parent links to the starting point. Add an edge. No need # to check distance here because we're already at the start # node. g.add_edge(parent_authority.pk, child_authority.pk) _ = set_shortest_path_to_end( good_nodes, node_id=parent_authority.pk, target_id=child_authority.pk, ) elif child_authority.pk in good_nodes: # Parent links to a node already in the network. Check if we # could make it to the end in max_dod hops. Set # shortest_path for the child_authority if within_max_hops(good_nodes, child_authority.pk, hops_taken, max_hops): g.add_edge(parent_authority.pk, child_authority.pk) is_shorter = set_shortest_path_to_end( good_nodes, node_id=parent_authority.pk, target_id=child_authority.pk, ) if is_shorter: # New route to a node that's shorter than the old # route. Thus, we must re-recurse its children. sub_graph = self.build_nx_digraph( parent_authority=child_authority, visited_nodes=visited_nodes, good_nodes=good_nodes, max_hops=max_hops, hops_taken=hops_taken, max_nodes=max_nodes, ) else: # No easy shortcuts. Recurse. sub_graph = self.build_nx_digraph( parent_authority=child_authority, visited_nodes=visited_nodes, good_nodes=good_nodes, max_hops=max_hops, hops_taken=hops_taken, max_nodes=max_nodes, ) if graphs_intersect(good_nodes, g, sub_graph): # The graphs intersect. Merge them. g.add_edge(parent_authority.pk, child_authority.pk) _ = set_shortest_path_to_end( good_nodes, node_id=parent_authority.pk, target_id=child_authority.pk, ) g = networkx.compose(g, sub_graph) if len(g) > max_nodes: raise TooManyNodes() return g def add_clusters(self, g): """Add clusters to the model using an existing nx graph. """ self.clusters.add(*g.nodes()) self.save() def to_json(self, g): """Make a JSON representation of a NetworkX graph of the data. """ j = { "meta": { "donate": "Please consider donating to support more projects " "from Free Law Project", "version": 1.1, }, } opinion_clusters = [] for cluster in self.clusters.all(): opinions_cited = {} for node in g.neighbors(cluster.pk): opinions_cited[node] = {'opacitiy': 1} opinion_clusters.append({ "id": cluster.pk, "absolute_url": cluster.get_absolute_url(), "case_name": cluster.case_name, "case_name_short": cluster.case_name_short, "citation_count": g.in_degree(cluster.pk), "date_filed": cluster.date_filed.isoformat(), "decision_direction": cluster.scdb_decision_direction, "votes_majority": cluster.scdb_votes_majority, "votes_minority": cluster.scdb_votes_minority, "scdb_id": cluster.scdb_id, "sub_opinions": [{ "type": "combined", "opinions_cited": opinions_cited, }] }) j['opinion_clusters'] = opinion_clusters return json.dumps(j, indent=2) def __unicode__(self): return u'{pk}: {title}'.format( pk=getattr(self, 'pk', None), title=self.title ) def get_absolute_url(self): return reverse('view_visualization', kwargs={'pk': self.pk, 'slug': self.slug}) def make_title(self): """Make a title for the network Title tries to use the shortest possible case name from the starting and ending clusters plus the number of degrees. """ def get_best_case_name(obj): case_name_preference = [ obj.case_name_short, obj.case_name, obj.case_name_full ] return next((_ for _ in case_name_preference if _), u"Unknown") return u"{start} ({start_year}) to {end} ({end_year})".format( start=get_best_case_name(self.cluster_start), start_year=self.cluster_start.date_filed.year, end=get_best_case_name(self.cluster_end), end_year=self.cluster_end.date_filed.year, ) def save(self, *args, **kwargs): # Note that the title needs to be made first, so that the slug can be # generated from it. if not self.title: self.title = trunc(self.make_title(), 200, ellipsis=u'…') if self.published is True and self.date_published is None: # First time shared. self.date_published = now() if self.deleted is True and self.__original_deleted != self.deleted: # Item was just deleted. self.date_deleted = now() if self.pk is None: # First time being saved. self.slug = slugify(trunc(self.title, 75)) # If we could, we'd add clusters and json here, but you can't do # that kind of thing until the first object has been saved. super(SCOTUSMap, self).save(*args, **kwargs) self.__original_deleted = self.deleted
class Draft(models.Model): did = models.CharField(max_length=150, unique=True) blog = models.ForeignKey( Blog, on_delete=models.CASCADE, related_name='my_drafts', ) tags = models.ManyToManyField( 'draft.tag', blank=True, related_name='tagged_drafts', ) github_url = models.URLField(max_length=1100) title = models.CharField(max_length=100) slug = models.SlugField(max_length=107) abstract = models.TextField(max_length=200, blank=True) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(blank=True, null=True) hits = models.IntegerField(default=0) objects = DraftManager() def __str__(self): return self.did def get_absolute_url(self): kwargs = { 'blog': self.blog.username, 'slug': self.slug, } return reverse('draft', kwargs=kwargs) @property def favorites(self): return Blog.objects.filter( my_activities__draft=self, my_activities__favorited__isnull=False, ) @property def likes(self): return Blog.objects.filter( my_activities__draft=self, my_activities__liked__isnull=False, ) @property def views(self): return Blog.objects.filter( my_activities__draft=self, my_activities__viewed__isnull=False, ) def get_short_title(self, max_len=50): from .utils import shorten_string return shorten_string(self.title, max_len) @staticmethod def get_did(blog, slug): return f'{blog}/{slug}' class Meta: verbose_name = 'draft' verbose_name_plural = 'drafts'
class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Album', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('display', models.BooleanField(default=True, verbose_name='Public')), ('title', models.CharField(max_length=100)), ('link', models.URLField()), ('cover_art', models.ImageField(blank=True, null=True, upload_to='cover-art-photos/')), ('release_date', models.DateField()), ('label', models.CharField(default='Interline Records', max_length=150)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ], ), migrations.CreateModel( name='Artist', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('display_artist', models.BooleanField(default=False)), ('name', models.CharField(max_length=100)), ('slug', models.SlugField(null=True)), ('photo', models.ImageField(blank=True, null=True, upload_to='artist-photos/')), ('biography', models.TextField(blank=True, max_length=500, null=True)), ('contact_name', models.CharField(default='Interline Records', max_length=100, verbose_name='Contact / Management Name')), ('contact_link', models.URLField(default='https://www.interlinerecords.com', verbose_name='Contact / Management URL')), ('contact_email', models.EmailField(default='*****@*****.**', max_length=254, verbose_name='Contact / Management Email')), ('website', models.URLField(blank=True, null=True)), ('spotify', models.URLField(blank=True, null=True)), ('youtube', models.URLField(blank=True, null=True, verbose_name='YouTube')), ('bandcamp', models.URLField(blank=True, null=True)), ('itunes', models.URLField(blank=True, null=True, verbose_name='iTunes')), ('facebook', models.URLField(blank=True, null=True)), ('twitter', models.URLField(blank=True, null=True)), ('instagram', models.URLField(blank=True, null=True)), ('soundcloud', models.URLField(blank=True, null=True)), ('vimeo', models.URLField(blank=True, null=True)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ], ), migrations.CreateModel( name='Video', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('display', models.BooleanField(default=True, verbose_name='Public')), ('title', models.CharField(max_length=100)), ('link', models.URLField()), ('description', models.CharField(blank=True, max_length=200, null=True)), ('video_service', models.CharField(choices=[('yt', 'Youtube'), ('vm', 'Vimeo')], default='yt', max_length=2)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('artist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='videos', to='artists.Artist')), ], ), migrations.AddField( model_name='album', name='artist', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='albums', to='artists.Artist'), ), ]
class Account(models.Model): name = models.CharField(_('name'), max_length=255) url = models.SlugField(_('url'), max_length=255, unique=True) plan = models.ForeignKey('billing.Plan', verbose_name=_('plan'), null=True) total_storage = models.BigIntegerField(_('total storage'), default=0) date_created = models.DateTimeField(_('date created'), auto_now_add=True) is_active = models.BooleanField(_('active'), default=True) date_cancel = models.DateTimeField(_('cancellation date'), null=True, blank=True) stripe_customer_id = models.CharField(max_length=255, blank=True) unlimited_trial = models.BooleanField(_('unlimited trial'), default=False) logo = models.ImageField(_('logotype'), upload_to='logotypes/%Y%m%d', storage=file_storage, null=True, blank=True) send_notification = models.BooleanField(_('send email notifications'), default=True) send_invitations = models.BooleanField( _('send automatic email invitations for new users and meetings'), default=False) view_email = models.BooleanField(_('view email'), default=True) show_guide = models.BooleanField(_('getting started'), default=True) date_trial_ends = models.DateTimeField( _('trial end date'), blank=True, null=True, help_text= 'if this date is not set, then trial period ends %s days after account creation date' % settings.TRIAL_PERIOD) default_meetings_location = models.CharField(max_length=255, blank=True, null=True) enforce_2fa = models.BooleanField(_('enforce 2fa'), default=False) enable_social_logins = models.BooleanField(_('enable social logins'), default=True) @property def last_invoice_created(self): if not self.invoices.all().count(): return self.date_created return self.invoices.all().latest('created_at').created_at @property def total_storage_size(self): bytes = float(self.total_storage) if bytes >= 1099511627776: terabytes = bytes / 1099511627776 total_storage = '{:.2f} Tb'.format(terabytes) elif bytes >= 1073741824: gigabytes = bytes / 1073741824 total_storage = '{:.2f} Gb'.format(gigabytes) elif bytes >= 1048576: megabytes = bytes / 1048576 total_storage = '{:.2f} Mb'.format(megabytes) elif bytes >= 1024: kilobytes = bytes / 1024 total_storage = '{:.2f} Kb'.format(kilobytes) else: total_storage = '{:.2f} b'.format(bytes) return total_storage def get_next_billing_date(self): if not self.invoices.all().count(): if self.billing_settings.cycle == self.billing_settings.MONTH: return timezone.now() + relativedelta(months=+1) elif self.billing_settings.cycle == self.billing_settings.YEAR: return timezone.now() + relativedelta(years=+1) return self.invoices.all().latest().payed_period_end def get_next_pay_date(self): if not self.invoices.all().count(): if self.billing_settings.cycle == self.billing_settings.MONTH: return timezone.now() + relativedelta(months=+1) elif self.billing_settings.cycle == self.billing_settings.YEAR: return timezone.now() + relativedelta(years=+1) return self.invoices.all().latest().payed_period_end def next_subscr_up_to(self): if self.billing_settings.cycle == self.billing_settings.MONTH: return self.get_next_pay_date() + relativedelta(months=+1) elif self.billing_settings.cycle == self.billing_settings.YEAR: return self.get_next_pay_date() + relativedelta(years=+1) def get_next_pay_charge(self): if self.billing_settings.cycle == self.billing_settings.MONTH: return self.plan.month_price elif self.billing_settings.cycle == self.billing_settings.YEAR: return self.plan.year_price def get_last_numbers_card(self): return 'XXXX-XXXX-XXXX-{}'.format( self.billing_settings.card_number[12:16]) def has_card_number(self): return bool(self.billing_settings.card_number) def get_max_storage(self): return self.plan.max_storage_size def get_max_members(self): return self.plan.max_members_str def __unicode__(self): return self.name def get_absolute_url(self): return reverse('board_detail', kwargs={'url': self.url}) def can_be_activated(self): return self.date_cancel is None or self.date_cancel + timezone.timedelta( days=30) >= timezone.now() def trial_till_date(self): if self.date_trial_ends: return self.date_trial_ends if self.unlimited_trial: return timezone.now() + timezone.timedelta(days=363) return self.date_created + timezone.timedelta( days=settings.TRIAL_PERIOD) def is_trial(self): return self.unlimited_trial or self.trial_till_date() >= timezone.now() def trial_days_left(self): if self.unlimited_trial: return 999 now = timezone.now() if self.date_trial_ends: return (self.date_trial_ends - now).days return settings.TRIAL_PERIOD - (now - self.date_created).days def get_admin_memberships(self): from profiles.models import Membership return self.memberships.filter( is_admin=True, is_active=True, invitation_status=Membership.INV_INVITED) def _create_subscription(self, elements_token=None): data = {} stripe_plan = self.plan.stripe_month_plan_id plan_fee = self.plan.month_price if self.billing_settings.cycle == BillingSettings.YEAR: stripe_plan = self.plan.stripe_year_plan_id plan_fee = self.plan.year_price stripe.api_key = settings.STRIPE_SECRET_KEY old_stripe_customer_id = self.stripe_customer_id try: # create card token if elements_token is None: # old-style with saved credentials, should be removed token_response = stripe.Token.create(card={ 'number': self.billing_settings.card_number, 'exp_month': self.billing_settings.expiration_month, 'exp_year': self.billing_settings.expiration_year, 'cvc': self.billing_settings.cvv, }, ) else: token_response = elements_token self.billing_settings.last4 = token_response['card']['last4'] self.billing_settings.expiration_month = token_response[ 'card']['exp_month'] self.billing_settings.expiration_year = token_response['card'][ 'exp_year'] self.billing_settings.card_type = token_response['card'][ 'type'] self.billing_settings.save() # create stripe subscription parameters = { 'description': self.name, 'email': self.billing_settings.mail, 'card': token_response['id'], 'plan': stripe_plan, } if self.is_trial(): # So that user will be first charged at this date. parameters['trial_end'] = int( time.mktime(self.trial_till_date().timetuple())) if self.billing_settings.discount: parameters['coupon'] = self.billing_settings.discount customer = stripe.Customer.create(**parameters) self.stripe_customer_id = customer.id self.save() logger.info("new stripe customer created id=%s, parameters=%s", customer.id, parameters) # create invoice timestamp_period_end = datetime.fromtimestamp( int(customer.subscription.current_period_end)) period_end = timestamp_period_end.replace(tzinfo=timezone.utc) Invoice.objects.create(payment=plan_fee, status=Invoice.PAID, account=self, payed_period_end=period_end) data = {'status': 'success', 'account': self} # delete subscriptions old credit cards, if it was if old_stripe_customer_id: try: c = stripe.Customer.retrieve(old_stripe_customer_id) c.cancel_subscription() logger.info( 'old subscription canceled for stripe customer %s', old_stripe_customer_id) except Exception as e: # Just in case it doesn't fall in items below: mail_admins( 'Stripe API Error', 'Problem with cancelling subscription for customer %s' % (old_stripe_customer_id, ), fail_silently=True) raise e except stripe.error.StripeError as e: errs = e.json_body.get('error', {}) if e.json_body is not None else {} errtxt = "\n".join(["%s = %s" % (k, v) for k, v in errs.items()]) mail_admins('Stripe Error', "@_create_subscription\n%s\n%s" % (errtxt, str(e)), fail_silently=True) logger.error("stripe error %s", str(e)) data = { 'status': 'error', 'msg': errs.get('message', 'Something went wrong..') } return data def _update_card(self, token=None): if not self.stripe_customer_id: return {'status': 'error', 'msg': 'No subscription to update.'} if 'card' not in token or 'id' not in token: return {'status': 'error', 'msg': 'Invalid token.'} stripe.api_key = settings.STRIPE_SECRET_KEY try: # update stripe c = stripe.Customer.retrieve(self.stripe_customer_id) c.source = token.get('id') c.save() # update local billing settings card = token.get('card', {}) self.billing_settings.last4 = card.get('last4') self.billing_settings.expiration_month = card.get('exp_month') self.billing_settings.expiration_year = card.get('exp_year') self.billing_settings.card_type = card.get('type') self.billing_settings.save() logger.info("card updated: customer=%s, token=%s card=%s", self.stripe_customer_id, token.get('id'), card) return {'status': 'success', 'msg': 'source card updated'} except stripe.error.StripeError as e: errs = e.json_body.get('error', {}) if e.json_body is not None else {} errtxt = "\n".join(["%s = %s" % (k, v) for k, v in errs.items()]) mail_admins('Stripe Error', "@_update_card\n%s\n%s" % (errtxt, str(e)), fail_silently=True) logger.error("stripe error %s", str(e)) return { 'status': 'error', 'msg': errs.get('message', 'Something went wrong...') } except Exception as e: return {'status': 'error', 'msg': str(e)} def _update_subscription(self): stripe_plan = self.plan.stripe_month_plan_id if self.billing_settings.cycle == BillingSettings.YEAR: stripe_plan = self.plan.stripe_year_plan_id stripe.api_key = settings.STRIPE_SECRET_KEY if self.stripe_customer_id: try: c = stripe.Customer.retrieve(self.stripe_customer_id) c.update_subscription(plan=stripe_plan, prorate=True) logger.info("subscription updated: customer=%s, plan=%s", self.stripe_customer_id, stripe_plan) return {'status': 'success'} except stripe.InvalidRequestError as e: mail_admins('Stripe Invalid Request Error', e.json_body['error']['message'], fail_silently=True) self.stripe_customer_id = '' self.save() return { 'status': 'error', 'msg': e.json_body['error']['message'] } else: return {'status': 'error', 'msg': 'No subscription to update.'} def _cancel_subscription(self): stripe.api_key = settings.STRIPE_SECRET_KEY if self.stripe_customer_id: try: c = stripe.Customer.retrieve(self.stripe_customer_id) c.cancel_subscription() except stripe.InvalidRequestError as e: mail_admins('Stripe Invalid Request Error', e.json_body['error']['message'], fail_silently=True) def extension(self): name, extension = os.path.splitext(self.logo.name) ext = extension[1:] if ext == 'png': return ext elif ext in ['jpg', 'jpeg']: return 'jpeg' else: return 'gif' @property def type(self): return 'logo' def clean(self): self.send_notification = not self.send_notification def get_path_to_discussion(self): return reverse('discussion:organization', kwargs={'url': self.url})
class Calendar(ImageMixin): objects = CalendarManager() name = models.CharField(_("titre"), max_length=255) slug = models.SlugField(_("slug"), unique=True) archived = models.BooleanField("Calendrier archivé", default=False) parent = models.ForeignKey( "Calendar", on_delete=models.SET_NULL, related_name="children", related_query_name="child", null=True, blank=True, ) events = models.ManyToManyField("Event", related_name="calendars", through="CalendarItem") user_contributed = models.BooleanField( _("Les utilisateurs peuvent ajouter des événements"), default=False) description = models.TextField( _("description"), blank=True, help_text=_("Saisissez une description (HTML accepté)"), ) image = StdImageField( _("bannière"), upload_to=FilePattern( filename_pattern= "{app_label}/{model_name}/{instance.name:slug}{ext}"), variations={ "thumbnail": (400, 250), "banner": (1200, 400) }, blank=True, ) class Meta: verbose_name = _("Agenda") def __str__(self): return self.name def clean_fields(self, exclude=None): super().clean_fields() if exclude is None: exclude = [] if "parent" not in exclude: calendar = self for i in range(settings.CALENDAR_MAXIMAL_DEPTH): calendar = calendar.parent if calendar is None: break else: raise ValidationError({ "parent": ValidationError( _("Impossible d'utiliser ce calendrier comme parent :" " cela excéderait la profondeur maximale autorisée.") ) })
class Migration(migrations.Migration): initial = True dependencies = [ ('contenttypes', '0002_remove_content_type_name'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Cart', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('total_products', models.PositiveIntegerField(default=0)), ('final_price', models.DecimalField(decimal_places=2, max_digits=9, verbose_name='Общая цена')), ], ), migrations.CreateModel( name='Category', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=255, verbose_name='Имя категории')), ('slug', models.SlugField(unique=True)), ], ), migrations.CreateModel( name='Specs', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('object_id', models.PositiveIntegerField()), ('name', models.CharField(max_length=255, verbose_name='Имя товара для характеристик')), ('content', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), ], ), migrations.CreateModel( name='Customer', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('phone', models.CharField(max_length=20, verbose_name='Номер телефона')), ('address', models.CharField(max_length=255, verbose_name='Адрес')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Пользователь')), ], ), migrations.CreateModel( name='CartProduct', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('object_id', models.PositiveIntegerField()), ('quantity', models.PositiveIntegerField(default=1)), ('final_price', models.DecimalField(decimal_places=2, max_digits=9, verbose_name='Общая цена')), ('cart', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='related_products', to='mainapp.cart', verbose_name='Корзина')), ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mainapp.customer', verbose_name='Покупатель')), ], ), migrations.AddField( model_name='cart', name='owner', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mainapp.customer', verbose_name='Владелец'), ), migrations.AddField( model_name='cart', name='products', field=models.ManyToManyField(blank=True, related_name='related_cart', to='mainapp.CartProduct'), ), ]
class Product(models.Model): product_unique_id = models.CharField(max_length=120, blank=True, unique=True, null=True, verbose_name=_('Product ID')) name = models.CharField(max_length=150, blank=False, unique=True, verbose_name=_('Name')) active = models.BooleanField(default=True, verbose_name=_('Active')) featured = models.BooleanField(default=False, verbose_name=_('Featured')) best_seller = models.BooleanField(default=False, verbose_name=_('Best Seller')) slug = models.SlugField(blank=True, unique=True, null=True, verbose_name=_('Slug')) tags = TaggableManager(blank=True) brand_information = models.ForeignKey( ProductBrand, blank=True, on_delete=models.SET_NULL, null=True, verbose_name=_('Brand Information')) model_information = models.ForeignKey( ProductModel, blank=True, on_delete=models.SET_NULL, null=True, verbose_name=_('Model Information')) sku = models.CharField(max_length=50, blank=True, verbose_name=_('Stock Keeping Unit')) description = models.TextField(blank=True, verbose_name=_('Description')) # size = models.ManyToManyField(ProductSize, blank=True, verbose_name=_('Size')) # color = models.ManyToManyField(ProductColor, blank=True, verbose_name=_('Color')) purchase_price = models.DecimalField( max_digits=25, decimal_places=2, verbose_name=_('Purchase Price')) old_purchase_price = models.DecimalField( max_digits=25, decimal_places=2, default=Decimal(0.00), blank=True, verbose_name=_('Old Purchase Price')) sale_price = models.DecimalField(max_digits=25, decimal_places=2, verbose_name=_('Sale Price')) old_sale_price = models.DecimalField( max_digits=25, decimal_places=2, default=Decimal(0.00), blank=True, verbose_name=_('Old Sale Price')) vat = models.ForeignKey(ProductVAT, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_('VAT')) category = models.ManyToManyField(ProductCategory, verbose_name=_('Category')) supplier = models.ManyToManyField(Supplier, verbose_name=_('Supplier')) sold_qty = models.PositiveIntegerField(default=0, blank=True, verbose_name=_('Sold Quantity')) purchased_stock = models.PositiveSmallIntegerField(default=0, blank=True, verbose_name=_('Purchased Stock')) available_stock = models.IntegerField(default=0, blank=True, verbose_name=_('Available Stock')) meta_keywords = models.CharField( max_length=255, blank=True, verbose_name=_('META Keywords'), help_text=_('Comma-delimited set of SEO keywords for meta tag')) meta_description = models.CharField( max_length=255, blank=True, verbose_name=_('META Description'), help_text=_('Content for description meta tag')) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_('Create date of Product')) updated_at = models.DateTimeField(auto_now=True, verbose_name=_('Update date of Product')) objects = ProductManager() def __str__(self): return self.name class Meta: ordering = ['-updated_at'] verbose_name = _('Product') verbose_name_plural = _('Products') def save(self, *args, **kwargs): self.sale_price = calculate_nearest_half(self.sale_price) super(Product, self).save(*args, **kwargs) def get_files(self): qs = self.productfile_set.all() return qs def get_product_purchase_count(self): return self.productpurchase_set.count() def get_billing_profiles(self): return self.productpurchase_set.all() def get_categories(self): return ', '.join([str(i) for i in self.category.all()])
class Account(models.Model, EntityMixin, DomainRuleMixin): """ A mercadopago account, aka "application". """ class Meta: verbose_name = _('account') verbose_name_plural = _('accounts') uuid = models.UUIDField( default=uuid.uuid4, editable=False, unique=True, primary_key=True ) name = models.CharField( _('name'), max_length=32, help_text=_('A friendly name to recognize this account.'), null=False, blank=False, ) slug = models.SlugField( _('slug'), max_length=64, unique=True, help_text=_("This slug is used for this account's notification URL."), null=False, blank=False, ) app_id = models.CharField( _('client id'), max_length=16, help_text=_('The APP_ID given by MercadoPago.'), editable=False, ) secret_key = models.CharField( _('secret key'), max_length=32, help_text=_('The SECRET_KEY given by MercadoPago.'), null=False, blank=False, ) sandbox = models.BooleanField( _('sandbox'), default=True, help_text=_( 'Indicates if this account uses the sandbox mode, ' 'indicated for testing rather than real transactions.' ), ) active = models.BooleanField( _('active'), default=True, help_text=_( 'Indicates that Account can be used to process process payments.' ), ) created_at = models.DateTimeField( _('created at'), auto_now_add=True, null=False, blank=False, editable=False, ) updated_at = models.DateTimeField( _('updated at'), auto_now=True, null=False, blank=False, editable=False, ) def __repr__(self): return '<Account {}: {}>'.format(self.pk, self.name) def __str__(self): return self.name
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('shop', '0002_auto_20160714_1249'), ] operations = [ migrations.CreateModel( name='Order', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('fullname', models.CharField(max_length=255, verbose_name='Fullname')), ('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-mail')), ('shipping_address', models.TextField(blank=True, null=True, verbose_name='Shipping address')), ('shipping_cost', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Cost')), ('is_paid', models.BooleanField(default=False, verbose_name='Is paid')), ('paid_sum', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='Paid sum')), ('discount_percent', models.DecimalField(decimal_places=2, default=0, max_digits=5, verbose_name='Discount')), ('date_created', models.DateTimeField(auto_now_add=True)), ('date_modified', models.DateTimeField(auto_now_add=True)), ], options={ 'ordering': ['-date_created'], 'abstract': False, 'verbose_name': 'order status', 'verbose_name_plural': 'order statuses', }, ), migrations.CreateModel( name='OrderDetail', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(blank=True, max_length=255, verbose_name='Code')), ('name', models.CharField(max_length=1024, verbose_name='Name')), ('price', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Price')), ('quantity', models.IntegerField(default=0, verbose_name='Quantity')), ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='details', to='shop.Order', verbose_name='Order')), ], options={ 'ordering': ['name'], 'abstract': False, 'verbose_name': 'order_datil', 'verbose_name_plural': 'order_datils', }, ), migrations.CreateModel( name='OrderPaymentType', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(unique=True, verbose_name='URL')), ('name', models.CharField(max_length=100, verbose_name='Name')), ('description', dartcms.utils.fields.RteField(blank=True, default=b'', verbose_name='Description')), ('is_enabled', models.BooleanField(default=True, verbose_name='Is enabled')), ('sort', models.IntegerField(default=1)), ('date_created', models.DateTimeField(auto_now_add=True)), ], options={ 'ordering': ['sort'], 'abstract': False, 'verbose_name': 'payment type', 'verbose_name_plural': 'payment types', }, ), migrations.CreateModel( name='OrderShippingType', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(unique=True, verbose_name='URL')), ('name', models.CharField(max_length=100, verbose_name='Name')), ('description', dartcms.utils.fields.RteField(blank=True, default=b'', verbose_name='Description')), ('cost', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Cost')), ('is_enabled', models.BooleanField(default=True, verbose_name='Is enabled')), ('sort', models.IntegerField(default=1)), ('date_created', models.DateTimeField(auto_now_add=True)), ], options={ 'ordering': ['sort'], 'abstract': False, 'verbose_name': 'shipping type', 'verbose_name_plural': 'shipping types', }, ), migrations.CreateModel( name='OrderStatus', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(unique=True, verbose_name='URL')), ('name', models.CharField(max_length=100, verbose_name='Name')), ('description', dartcms.utils.fields.RteField(blank=True, default=b'', verbose_name='Description')), ('is_enabled', models.BooleanField(default=True, verbose_name='Is enabled')), ('sort', models.IntegerField(default=1)), ('date_created', models.DateTimeField(auto_now_add=True)), ], options={ 'ordering': ['sort'], 'abstract': False, 'verbose_name': 'order status', 'verbose_name_plural': 'order statuses', }, ), migrations.AlterField( model_name='product', name='manufacturer', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='manufacturer_products', to='shop.ProductManufacturer', verbose_name='Manufacturer'), ), migrations.AddField( model_name='orderdetail', name='product', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.Product', verbose_name='Product'), ), migrations.AddField( model_name='order', name='payment_type', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.OrderPaymentType', verbose_name='Payment type'), ), migrations.AddField( model_name='order', name='shipping_type', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.OrderShippingType', verbose_name='Shipping type'), ), migrations.AddField( model_name='order', name='status', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='shop.OrderStatus', verbose_name='Status'), ), migrations.AddField( model_name='order', name='user', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='User'), ), ]
class SlugBasedModel(RESTFrameworkModel): text = models.CharField(max_length=100) slug = models.SlugField(max_length=32)
class Product(models.Model): ''' The ``Product`` model represents a particular item in a catalog of products. It contains information about the product for sale, which is common to all items in the catalog. These include, for example, the item's price, manufacturer, an image or photo, a description, etc. ''' name = models.CharField( _("Full Name"), max_length=255, blank=False, help_text= _("This is what the product will be called in the default site language." )) slug = models.SlugField( _("Item No."), max_length=255, blank=True, unique=True, help_text=_("Used for URLs, auto-generated from name if blank"), ) sku = models.CharField(_("Model No."), max_length=255, blank=True, null=True, help_text=_("Defaults to slug if left blank.")) short_description = models.TextField( _("Short description of product"), help_text= _("This should be a 1 or 2 line description for use in product listing screens" ), max_length=200, default='', blank=True) description = PlaceholderField("product_description") active = models.BooleanField(_("Active"), default=True, help_text=_("Is product Active?")) categories = models.ManyToManyField(Category, blank=True, null=True, verbose_name=_('Categories'), related_name='products') ordering = models.IntegerField( _("Ordering"), default=0, help_text=_("Override alphabetical order in category display")) featured = models.BooleanField( _("Featured Item"), default=False, help_text=_("Featured items will show on the front page")) date_added = models.DateField(_("Date added"), null=True, blank=True, default=date.today) objects = ActiveManager() class Meta: ordering = ['ordering', 'name'] verbose_name = _('Product') verbose_name_plural = _('Products') def __unicode__(self): return u'%s' % self.name @models.permalink def get_absolute_url(self): return ('catalog.views.product_detail', (), {'slug': self.slug}) def save(self, *args, **kw): if self.name and not self.slug: self.slug = slugify(self.name, instance=self) if not self.sku: self.sku = self.slug super(Product, self).save(*args, **kw) @property def main_image(self): img = None if self.images.count() > 0: img = self.images.order_by('sort')[0] if not img: #This should be a "Image Not Found" placeholder image try: img = ProductImage.objects.filter( product__isnull=True).order_by('sort')[0] except IndexError: pass return img def get_price(self, **kwargs): return self.prices.active().filter(**kwargs).latest() @property def price(self): return self.get_price(currency=DEFAULT_CURRENCY) @property def original_price(self): return self.get_price(currency=DEFAULT_CURRENCY, is_sale=False) @property def sale_price(self): return self.get_price(currency=DEFAULT_CURRENCY, is_sale=True) @property def discount(self): original = self.original_price if not original: return 0 sale = self.sale_price or original return " %s%%" % round( 100 * (original.unit_price - sale.unit_price) / original.unit_price, 2)
class Migration(migrations.Migration): dependencies = [("contenttypes", "0001_initial")] operations = [ migrations.CreateModel( name="Tag", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, help_text="", verbose_name="ID", ), ), ( "name", models.CharField(help_text="", unique=True, max_length=100, verbose_name="Name"), ), ( "slug", models.SlugField(help_text="", unique=True, max_length=100, verbose_name="Slug"), ), ], options={ "verbose_name": "Tag", "verbose_name_plural": "Tags" }, bases=(models.Model, ), ), migrations.CreateModel( name="TaggedItem", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, help_text="", verbose_name="ID", ), ), ( "object_id", models.IntegerField(help_text="", verbose_name="Object id", db_index=True), ), ( "content_type", models.ForeignKey( related_name="taggit_taggeditem_tagged_items", verbose_name="Content type", to="contenttypes.ContentType", help_text="", on_delete=models.CASCADE, ), ), ( "tag", models.ForeignKey( related_name="taggit_taggeditem_items", to="taggit.Tag", help_text="", on_delete=models.CASCADE, ), ), ], options={ "verbose_name": "Tagged Item", "verbose_name_plural": "Tagged Items", }, bases=(models.Model, ), ), ]
class Migration(migrations.Migration): initial = True dependencies = [ ('accounts', '0002_auto_20190326_1754'), ] operations = [ migrations.CreateModel( name='Comment', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=80)), ('email', models.EmailField(max_length=254)), ('body', models.TextField()), ('created_on', models.DateTimeField(auto_now_add=True)), ('active', models.BooleanField(default=False)), ], options={ 'ordering': ['created_on'], }, ), migrations.CreateModel( name='Post', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=200, unique=True)), ('slug', models.SlugField(max_length=200, unique=True)), ('updated_on', models.DateTimeField(auto_now=True)), ('content', models.TextField()), ('created_on', models.DateTimeField(auto_now_add=True)), ('status', models.IntegerField(choices=[(0, 'Draft'), (1, 'Publish')], default=0)), ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='blog_posts', to='accounts.User')), ], options={ 'ordering': ['-created_on'], }, ), migrations.AddField( model_name='comment', name='post', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='blog.Post'), ), ]
class Article(models.Model): code = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Código de articulo') ) model = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Modelo') ) name = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Nombre') ) origin = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Origen') ) sales_unit = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Unidad de ventas') ) ref = models.CharField( max_length=256, null=True, blank=True, verbose_name=_('Referencia') ) # description = RichTextField(blank=True, verbose_name=_('Descripción'), max_length=2000) item_type = models.ForeignKey( Type, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Tipo de articulo'), ) line = models.ForeignKey( Line, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Linea') ) category = models.ForeignKey( Category, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Categoría') ) color = models.ForeignKey( Color, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Color') ) department = models.ForeignKey( Department, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Departamento') ) brand = models.ForeignKey( Brands, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Marca'), ) provider = models.ForeignKey( Provider, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Proveedor') ) sub_line = models.ForeignKey( SubLine, null=True, blank=True, on_delete=models.CASCADE, verbose_name=_('Sublinea') ) slug = models.SlugField( unique=True, blank=True, null=True, max_length=500, verbose_name=_('URL \"SEO\"') ) stock = models.IntegerField( default=0, blank=True, null=True, verbose_name=_('Stock') ) views = models.SmallIntegerField( default=0, blank=True, verbose_name=_('Numero de visitas') ) picture = models.ImageField( blank=True, null=True, upload_to=get_upload_path, verbose_name=_('Foto de articulo') ) price_1 = models.DecimalField( decimal_places=2, max_digits=99, blank=True, null=True, verbose_name=_('Precio 1') ) price_2 = models.DecimalField( decimal_places=2, max_digits=99, blank=True, null=True, verbose_name=_('Precio 2') ) price_3 = models.DecimalField( decimal_places=2, max_digits=99, blank=True, null=True, verbose_name=_('Precio 3') ) price_4 = models.DecimalField( decimal_places=2, max_digits=99, blank=True, null=True, verbose_name=_('Precio 4') ) price_5 = models.DecimalField( decimal_places=2, max_digits=99, blank=True, null=True, verbose_name=_('Precio 5') ) updated = models.DateTimeField( auto_now=True, auto_now_add=False, verbose_name=_('Ultima actualización') ) created_at = models.DateTimeField( auto_now=False, auto_now_add=True, verbose_name=_('Creado') ) img = models.ImageField( upload_to=get_art_upload_path,#"sales/arts/", blank=True, null=True, verbose_name=_('Imagen de articulo'), default='sales/arts/base.jpg' ) active = models.BooleanField( default=False, verbose_name=_('Activo') ) featured = models.BooleanField( default=False, verbose_name=_('Destacado') ) sale = models.BooleanField( default=False, verbose_name=_('En descuento') ) imported = models.BooleanField( default=False, verbose_name=_('Importado') ) is_shipping_required = models.BooleanField( default=False, verbose_name=_('Requiere envio') ) # def __str__(self): # return self.code def get_absolute_url(self): return reverse('sales:product_detail', kwargs={'slug': self.slug}) def counter(self): return len(self.objects.all()) def update_counter(self): self.views = self.views + 1 self.save() class Meta: ordering = ["-code","-views"] verbose_name = _('Producto') verbose_name_plural = _('Productos')
class Theme(models.Model): parentId = models.ForeignKey( 'self', null=True, blank=True, related_name="children", verbose_name=_('Theme parent')) title = models.CharField( _('Title'), max_length=100, help_text=_("Please choose a title as short and accurate as " "possible, reflecting the main subject / context " "of the content.(max length : 100 characters)")) slug = models.SlugField( _('Slug'), max_length=100, help_text=_( u'Used to access this instance, the "slug" is a short label ' + 'containing only letters, numbers, underscore or dash top.'), editable=False) description = models.TextField( _('Description'), null=True, blank=True, help_text=_("In this field you can describe your content, " "add all needed related information, and " "format the result using the toolbar.")) headband = models.ForeignKey(CustomImageModel, models.SET_NULL, blank=True, null=True, verbose_name=_('Headband')) channel = models.ForeignKey( 'Channel', related_name='themes', verbose_name=_('Channel')) def __str__(self): return "%s: %s" % (self.channel.title, self.title) def get_absolute_url(self): return reverse('theme', args=[str(self.channel.slug), str(self.slug)]) def save(self, *args, **kwargs): self.slug = slugify(self.title) super(Theme, self).save(*args, **kwargs) def get_all_children_tree(self): children = {} # [self] try: child_list = self.children.all() except AttributeError: return children for child in child_list: children["%s" % child.id] = { "title": "%s" % child.title, "slug": "%s" % child.slug, "url": "%s" % child.get_absolute_url(), "child": child.get_all_children_tree() } return children def get_all_children_flat(self): children = [self] try: child_list = self.children.all() except AttributeError: return children for child in child_list: children.extend(child.get_all_children_flat()) return children def get_all_children_tree_json(self): return json.dumps(self.get_all_children_tree()) def get_all_parents(self): parents = [self] if self.parentId is not None: parent = self.parentId parents.extend(parent.get_all_parents()) return parents def clean(self): if Theme.objects.filter( channel=self.channel, slug=slugify(self.title)).exists(): raise ValidationError( "A theme with this name already exist in this channel.") if self.parentId in self.get_all_children_flat(): raise ValidationError("A theme cannot have itself \ or one of it's children as parent.") if self.parentId and self.parentId not in self.channel.themes.all(): raise ValidationError( "A theme have to be in the same channel that his parent") class Meta: ordering = ['channel', 'title'] verbose_name = _('Theme') verbose_name_plural = _('Themes') unique_together = ("channel", "slug")
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('userprofile', '0011_auto_20171109_2242'), ] operations = [ migrations.CreateModel( name='Students', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', models.SlugField(blank=True, null=True, unique=True)), ('Student_name', models.CharField(max_length=100)), ('Student_category', models.CharField(choices=[('MO', 'M.Tech. Students Ongoing'), ('MC', 'M.Tech. Students Completed'), ('PO', 'Ph.D. Students continuing'), ('PC', 'Ph.D. Students Completed')], default='select', max_length=2)), ('Thesis_title', models.CharField(max_length=3000)), ('Supervisors', models.CharField(max_length=3000)), ('username', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='Student', to=settings.AUTH_USER_MODEL)), ], ), migrations.AlterField( model_name='teaching', name='Partners', field=models.CharField(max_length=200), ), migrations.AlterField( model_name='teaching', name='semester', field=models.CharField(choices=[('E', 'Even Semester'), ('O', 'Odd Semester')], default='select', max_length=1), ), migrations.AlterField( model_name='teaching', name='year', field=models.IntegerField(choices=[(1950, 1950), (1951, 1951), (1952, 1952), (1953, 1953), (1954, 1954), (1955, 1955), (1956, 1956), (1957, 1957), (1958, 1958), (1959, 1959), (1960, 1960), (1961, 1961), (1962, 1962), (1963, 1963), (1964, 1964), (1965, 1965), (1966, 1966), (1967, 1967), (1968, 1968), (1969, 1969), (1970, 1970), (1971, 1971), (1972, 1972), (1973, 1973), (1974, 1974), (1975, 1975), (1976, 1976), (1977, 1977), (1978, 1978), (1979, 1979), (1980, 1980), (1981, 1981), (1982, 1982), (1983, 1983), (1984, 1984), (1985, 1985), (1986, 1986), (1987, 1987), (1988, 1988), (1989, 1989), (1990, 1990), (1991, 1991), (1992, 1992), (1993, 1993), (1994, 1994), (1995, 1995), (1996, 1996), (1997, 1997), (1998, 1998), (1999, 1999), (2000, 2000), (2001, 2001), (2002, 2002), (2003, 2003), (2004, 2004), (2005, 2005), (2006, 2006), (2007, 2007), (2008, 2008), (2009, 2009), (2010, 2010), (2011, 2011), (2012, 2012), (2013, 2013), (2014, 2014), (2015, 2015), (2016, 2016), (2017, 2017)], default=2017, verbose_name='year'), ), ]