class BaseProduct(models.Model): # MALE = # FEMALE = #SEX_CHOICES DEFAULT_SORT = '-popularity' name = models.CharField('Наименование', max_length=255, default='') categories = TreeManyToManyField('catalog.Category', related_name='base_products_list', blank=True, verbose_name='Категории') manual_categories = TreeManyToManyField('catalog.Category', related_name='manual_base_product_list', blank=True, verbose_name=' Категории добавленные вручную') remote_id = models.CharField('ID синхронизации', max_length=255, unique=True) brand = models.ForeignKey(Brand, on_delete=models.SET_NULL, related_name='products_list', blank=True, null=True) article = models.CharField('Артикул',max_length=255, default='', blank=True, null=True) colors = models.ManyToManyField(Color, related_name='products_list', blank=True, verbose_name='Цвета') sex = models. CharField('Пол', max_length=255, default='', blank=True) #choises = SEX_CHOICES materials = models.ManyToManyField(Material, related_name='product_list', blank=True, verbose_name='Материалы') prints = models.ManyToManyField(Print, related_name='product_list') attributes = JSONField('Дополнительные характеристики', default=dict, blank=True) is_sublimation = models.BooleanField('Сублимация', default=False) is_active = models.BooleanField('Активен', default=True) is_new = models.BooleanField('Новинка', default=False) importer = models.ForeignKey(Importer, on_delete=models.SET_NULL, related_name='product_list', null=True, verbose_name='Поставщик') #TODO возможно стоит заменить на M2M popularity = models.PositiveIntegerField('Популярность', default=0, blank=True) class Meta: verbose_name = 'Базовый товар' verbose_name_plural = 'Базовые товары' ordering = ('name',) def __str__(self): return self.name if self.name else ''
class Category(MPTTModel): """Категория""" name = models.CharField('название', max_length=64) cover = models.ImageField('обложка', upload_to='categories/%Y/%m/%d/', blank=True, null=True) parent = TreeForeignKey('self', models.CASCADE, blank=True, db_index=True, null=True, related_name='children', verbose_name='родительская категория') relations = TreeManyToManyField('self', blank=True, verbose_name='связанные категории') one_s_ids = models.TextField('Идентификаторы категорий в 1С', blank=True, null=True) def __str__(self): return self.name def save(self, *args, **kwargs): '''Удаление файла обложки категории при обновлении/удалении обложки''' try: post_object = self pre_object = post_object.__class__.objects.get(id=post_object.id) if pre_object.cover != post_object.cover: pre_object.cover.delete(save=False) except: pass super(self.__class__, self).save(*args, **kwargs) class Meta: verbose_name = 'категория' verbose_name_plural = 'категории'
class Ad(models.Model): title = models.CharField(max_length=200, verbose_name='Mahabatyň ady') slug = models.SlugField(max_length=200, verbose_name='URL') image = models.ImageField(upload_to="photos/%Y/%m/%d", blank=True, verbose_name='Surat') created_at = models.DateTimeField(auto_now_add=True, verbose_name='Döredilen wagt') cities = TreeManyToManyField(City, on_delete=models.CASCADE, null=True, blank=True, related_name='cities', verbose_name='Shaher') category = models.ForeignKey(Category, on_delete=models.PROTECT, null=True, blank=True, related_name='category', verbose_name='Kategoriýa') def __str__(self): return self.title class Meta: verbose_name = 'Mahabat' verbose_name_plural = 'Mahabatlar' ordering = ['-created_at', 'title']
class Vehicle(models.Model): picture = models.ImageField(upload_to=vehicle_images_path) name = models.CharField(max_length=64) model_name = models.CharField(max_length=64) description = models.TextField(max_length=512, blank=True, default='') date = models.DateTimeField('date', auto_now=True) verified = models.BooleanField(blank=True) owner = models.ForeignKey('auth.User', related_name='vehicles', on_delete=models.CASCADE, blank=True) types = TreeManyToManyField('VehicleType', related_name='types', blank=True) class Meta: ordering = ('name', ) def __str__(self): return self.name def save(self, *args, **kwargs): super(Vehicle, self).save(*args, **kwargs)
def handle_model(self): self.model.add_to_class( 'category', TreeManyToManyField( Category, null=False, blank=False, related_name="%(app_label)s_%(class)s_category", verbose_name='Раздел-категория-тег')) self.model.add_to_class( 'mediafile', MediaFileForeignKey(MediaFile, on_delete=models.SET_NULL, related_name='+', null=True, verbose_name='Картинка')) self.model.add_to_class('name_category', property(name_category)) self.model.add_to_class( 'url_img', property( lambda x: join(settings.MEDIA_URL, str(x.mediafile.file)))) self.model.add_to_class('stars', models.PositiveIntegerField(default=0)) self.model.add_to_class('count_for_r', models.PositiveIntegerField(default=0)) self.model.add_to_class( 'raiting', models.FloatField(default=0, verbose_name='Рейтинг'))
class Product(models.Model): title = 'Product' created_at = models.DateTimeField(verbose_name='Created at', auto_now_add=True) updated_at = models.DateTimeField(auto_now=True, verbose_name='Updated at') name = models.CharField(max_length=128) category = TreeManyToManyField(Category) image = models.ImageField(upload_to=upload_path, blank=True, null=True) short_description = models.CharField(max_length=64, blank=True, null=True, help_text='Maximum 64 symbols') description = models.TextField(max_length=1200, blank=True, null=True) price = MoneyField(max_digits=14, decimal_places=2, default_currency='EUR', blank=True, null=True, verbose_name='Price') manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE, default=1) # Place of origin, may not be equal to the country of manufacturer country = models.CharField(max_length=64, default='') publish = models.BooleanField(default=True) def __str__(self): return '%s' % self.name def get_absolute_url(self): return reverse('product', kwargs={"pk": self.pk})
class Repository(models.Model): name = models.CharField(max_length=200, default='') alt_names = models.CharField(max_length=200, blank=True, default='') url = models.URLField(verbose_name="Repository URL") persistent_url = models.URLField(null=True, blank=True, default='') accepted_taxonomy = TreeManyToManyField('Taxonomy', ) accepted_content = TreeManyToManyField('ContentType', ) #standards = models.ForeignKey('Standards', related_name='standards', null=True) description = models.CharField(max_length=2000, blank=True, default='') hosting_institution = models.CharField(max_length=1000, blank=True, default='') institution_country = models.CharField(max_length=100, blank=True, default='') owner = models.ForeignKey('auth.User', related_name='repositorys', null=True, blank=True) contact = models.CharField(max_length=500, blank=True, default='') metadataInformationURL = models.URLField( verbose_name="Metadata Information URL", blank=True) metadataRemarks = models.CharField(max_length=1000, blank=True, default='', verbose_name="Metadata Remarks") size = models.CharField(max_length=500, blank=True, default='') date_operational = models.DateField(default=datetime.date.today()) created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') remarks = models.CharField(max_length=10000, blank=True, default='') embargoed = models.BooleanField(default=True, verbose_name='Hidden on site') allows_embargo_period = models.BooleanField(default=False) doi_provided = models.BooleanField(default=False) links_to_publications = models.BooleanField(default=False) db_certifications = TreeManyToManyField('Certification', blank=True) class Meta: ordering = ('name', ) verbose_name_plural = 'Repositories' def __str__(self): return str(self.name)
class Product(models.Model): category = TreeManyToManyField('Category') product_name = models.CharField(max_length=254, default='') search_price = models.DecimalField(max_digits=6, decimal_places=2) aw_image_url = models.CharField(max_length=500, default='') merchant_deep_link = models.CharField(max_length=500, default='') slug = models.SlugField(default='product') def __str__(self): return self.product_name
class CustomUser(User): region = TreeManyToManyField(Region, blank=True, related_name='user_region') def __str__(self): return self.phone_number def __unicode__(self): return self.phone_number
class Blog(models.Model): rss_url = models.URLField(max_length=255, unique=True) url = models.URLField(max_length=255, default='') projects = TreeManyToManyField(Project, related_name='blogs', blank=True) last_updated = models.DateTimeField(blank=True, null=True, default=None) objects = get_natural_key_manager('rss_url') def __str__(self): return self.url
class ObjectCode(models.Model): object_id = models.UUIDField(primary_key=True, default=uuid.uuid1, editable=False) object_name = models.CharField(verbose_name=u'名称', max_length=30, null=True) object_value = models.CharField(max_length=40, null=True) model = models.ForeignKey( BasicModel, verbose_name=u'基础模型', related_name='model_material', on_delete=models.CASCADE, ) #limit_choices_to={'model_value__istartswith': 'Material'}, ) category = TreeManyToManyField( Category, verbose_name=u'编码分类', ) #limit_choices_to={'category_value__istartswith': 'Material', 'if_sealed': True}) type = models.CharField(verbose_name=u'类型', max_length=30) specification = models.CharField(verbose_name=u'规格', max_length=30, blank=True, null=True) unit = models.CharField(verbose_name=u'单位', max_length=30, blank=True, null=True) create_by = models.CharField(max_length=30, blank=True, null=True) create_time = models.DateTimeField(auto_now_add=True, blank=True, null=True) update_by = models.CharField(max_length=30, blank=True, null=True) update_time = models.DateTimeField(auto_now=True, blank=True, null=True) del_flag = models.BooleanField(blank=True, null=True) remark = models.CharField(max_length=50, blank=True, null=True) @property def full_name(self): if not (self.specification is None): return '%s_%s' % (self.type, self.specification) else: return '%s' % (self.type) def __str__(self): return self.full_name class Meta: verbose_name = u"3.系统编码" verbose_name_plural = u"3.系统编码"
class Book(models.Model): title = models.CharField(max_length=300) Author = models.ManyToManyField(Author, blank=True) description = models.TextField(blank=True, db_index=True) slug = models.SlugField(max_length=150, unique=True) image = models.ImageField(blank=True) comments = models.ManyToManyField(Comments, blank=True) Rewiew = models.ForeignKey(Rewiew, on_delete=models.CASCADE) genreTree = TreeManyToManyField(Genre, related_name='books') like = models.ManyToManyField(User, blank=True, related_name='likes') def __str__(self): return str(self.title)
class Ad(models.Model): title = models.CharField(max_length=30, help_text='Title ads', db_column='data') date_create = models.DateTimeField(auto_now=True, help_text='Date Create') description = models.TextField(max_length=300) region = TreeManyToManyField(Region, blank=True, related_name='reg') category = TreeManyToManyField(Category, blank=True, related_name='ad') views = models.IntegerField(blank=True, null=True) price = models.IntegerField(blank=True, null=True) phone_number = PhoneNumberField(blank=True) user = models.ForeignKey(CustomUser, related_name='ads', on_delete=models.CASCADE, blank=True, null=True) is_active = models.BooleanField(default=True) def __str__(self): return self.title @classmethod def create_ad(self, title, description, price, region, category, user): try: add_ad = Ad(title=title, description=description, price=price, user=user) add_ad.save() for cat in category: add_ad.category.add(cat) for reg in region: add_ad.region.add(reg) return add_ad except Exception as e: raise
class Question(models.Model): exam = models.ForeignKey(Exam, on_delete=models.CASCADE) qnumber = models.CharField(max_length=100) qorder = models.DecimalField(decimal_places=2, max_digits=6) syllabuspoint = models.ManyToManyField(SyllabusPoint, blank=True) maxscore = models.IntegerField() weighting = models.FloatField(default=1.0, blank=False, null=False) MPTTsyllabuspoint = TreeManyToManyField('MPTTSyllabus') def __str__(self): return self.qnumber class Meta: unique_together = (("exam", "qorder"),)
class MailingList(models.Model): posting_address = models.EmailField(unique=True) archive_url = models.CharField(max_length=10000) last_updated = models.DateTimeField(blank=True, null=True, default=None) projects = TreeManyToManyField(Project, through='MailingListProject', related_name='mailing_lists', blank=True) objects = get_natural_key_manager('posting_address') def __str__(self): return self.posting_address
class Article(models.Model): article_title = models.CharField('Заголовок', max_length = 100) article_announcement = models.CharField('Анонс', max_length = 250) article_text = models.TextField('Текст') author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True) genre = TreeManyToManyField(Genre, null=True, help_text="Выберите рубрику новости") def __str__(self): return self.article_title class Meta: verbose_name = 'Новость' verbose_name_plural = 'Новости'
class Clothes(Product): categories = TreeManyToManyField(ClothesCategory, verbose_name="Catégorie d'habits") class Meta: verbose_name = 'Habit' def get_entrees(self): return ClothesEntry.objects def get_sorties(self): return ClothesOutput.objects def get_absolute_url(self): return reverse('clothes:detail', kwargs={'pk' : self.pk})
class Article(TimeStampedModel): STATUS_CHOICES = ( ('draft', 'Draft'), ('published', 'Published') ) title = models.CharField("Article Title", max_length=255) featured_image = models.ImageField(upload_to="featured_images") slug = AutoSlugField("Article Address", unique=True, always_update=False, populate_from='title') author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.DO_NOTHING) content = RichTextUploadingField(config_name='default') is_featured = models.BooleanField(default=False) force_highlighted = models.BooleanField(default=False) categories = TreeManyToManyField('Category', blank=True) status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft') objects = models.Manager() # Default manager. published = PublishedManager() # Custom published manager. likes = models.ManyToManyField( 'Like', related_name='article_liked', blank=True) class Meta: ordering = ['-created'] get_latest_by = "created" def __str__(self): return self.title def get_absolute_url(self): return reverse('articles:detail', kwargs={'slug': self.slug}) def short_description(self): choices = [10, 15, 18] html = markdown(self.content) text = ''.join(BeautifulSoup(html).findAll(text=True)) text = text.replace('\xa0', ' ').replace('\n', ' ').split(' ') return ' '.join(text[:choice(choices)]) def get_related_articles(self): try: articles = self.categories.last().article_set.all() except: articles = [] return articles
class Order(AbstractDeal): """Заявка - объявление""" PAYMENT_METHOD_CHOICES = ( ('for_cash', 'Наличными'), ('non_cash', 'Безналичный расчет'), ) price_max = models.DecimalField("Максимальная цена", max_digits=8, decimal_places=2, default=0.00) date_validity = models.DateTimeField("Актуально до") category = TreeManyToManyField(Category, verbose_name="Категории", blank=True) payment_method = models.CharField('Способ оплаты', max_length=50, choices=PAYMENT_METHOD_CHOICES, default='for_cash') buyer = models.ForeignKey(User, verbose_name="Покупатель", on_delete=models.CASCADE) city = models.CharField("Город", max_length=50, blank=True, null=True) def __str__(self): return self.name def get_absolute_url(self): return reverse("order", kwargs={'pk': self.pk}) def save(self, *args, **kwargs): # при создании заявки в шаблоне создаем slug if not self.id: self.slug = gen_slug(self.name) super().save(*args, **kwargs) class Meta: verbose_name = "Заявка - объявление" verbose_name_plural = "Заявки - объявления" ordering = [ '-date_publication', ]
class BugNamespace(models.Model): bug_tracker = models.ForeignKey(BugTracker, related_name='namespaces') product = models.CharField(max_length=100, null=True, blank=True) component = models.CharField(max_length=100, null=True, blank=True) last_updated = models.DateTimeField(blank=True, null=True, default=None) projects = TreeManyToManyField(Project, related_name='bug_trackers', blank=True) objects = get_natural_key_manager('product', 'component', 'bug_tracker') def __str__(self): return '(%s, %s) on %s' % (self.product, self.component, self.bug_tracker) class Meta: unique_together = ('product', 'component', 'bug_tracker') verbose_name = "Bug Namespace"
class Product(models.Model): name = models.CharField(max_length=200) slug = models.SlugField(max_length=200, allow_unicode=True, null=True, blank=True, unique=True) available = models.BooleanField(default=True) description = RichTextField(blank=True, null=True) quantity = models.IntegerField(default=0, null=True, blank=True) base_price = models.DecimalField(max_digits=12, decimal_places=0, null=True, blank=True) price = models.DecimalField(max_digits=12, decimal_places=0) digital = models.BooleanField(default=False, null=True, blank=True) image = models.ImageField(null=True, blank=True) category = TreeManyToManyField(Category, blank=True) date_added = models.DateTimeField(auto_now_add=True, null=True, blank=True) def __str__(self): return self.name class Meta: verbose_name_plural = "محصولات" @property def imageURL(self): try: url = self.image.url except: url = '' return url def save(self, *args, **kwargs): self.slug = slugify(self.name, allow_unicode=True) #.replace(" ","-") if self.quantity <= 0: self.quantity = None super(Product, self).save()
class AbstractTaxonomy(MPTTModel): """Inherit from Taxonomy to create taxa. # Define collections attribute in subclass. """ groups = TreeManyToManyField('Role') parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) name = models.CharField(max_length=255) tags = TaggableManager(blank=True) class Meta: abstract = True app_label = 'dj_contentmodel' verbose_name_plural = "Category" verbose_name_plural = "Categories" class MPTTMeta: order_insertion_by = ['name'] def __unicode__(self): return self.name
class Accessory(Product): categories = TreeManyToManyField(AccessoryCategory, verbose_name='Catégorie accessoire') marque_ref = models.ForeignKey(AccessoryMarque, null=True, blank=True, help_text='Choix des marques') class Meta: verbose_name = 'Accessoire' permissions = (("view_achat", "Can view achats"), ) def get_absolute_url(self): return reverse('accessories:detail', kwargs={'pk': self.pk}) def get_entrees(self): return AccessoryEntry.objects def get_sorties(self): return AccessoryOutput.objects def get_marque_class(self): """Return the class AccessoryMarque""" return AccessoryMarque
class Book(models.Model): title = models.CharField(max_length=500) annotation = models.TextField() ISBN = models.CharField(max_length=255) publish_year = models.IntegerField( default=current_year(), validators=[MinValueValidator(1900), max_value_current_year]) language = models.ForeignKey(Language, default=None, on_delete=models.CASCADE, blank=True, null=True) slug = models.SlugField(max_length=500, unique=False, null=False) password = models.CharField(max_length=600) is_featured = models.BooleanField(default=False, help_text="Для рекомендуемых") book_cover = models.FileField(default=None, upload_to=upload_book_image, blank=True, null=False, max_length=1000) book_content_pdf = models.FileField( default=None, upload_to=upload_book_pdf, blank=True, null=False, validators=[FileExtensionValidator(['pdf'])], max_length=1000) authors = models.ManyToManyField(Author, related_name='books', blank=True) categories = TreeManyToManyField(Category, blank=True, related_name='books') def __str__(self): return self.title
class ListViewFilter(SortableMixin): """ Filter for bookings. Filters partition bookings into groups based on the filter attributes. When a filter is run, it outputs two sets of bookings, the bookings that belong to the group defined by the filter (in-set) and the bookings that do not match the attributes of the filter (out-set). The latter bookings are typically used as input for other filters to create a pipeline of filters. The following filter attributes can be set: - included_categories: type Category[] in-set: bookings of materials that have any of their categories in the supplied categories. out-set: bookings of materials for which none of its categories matches one of the supplied categories. - excluded_categories: type Category[] Note: the in-set and out-set are the swapped in-set and out-set for included_categories. in-set: bookings of materials for which none of its categories matches one of the supplied categories. out-set: bookings of materials that have any of their categories in the supplied categories. - gm: type bool in-set: bookings of materials for which the gm attribute matches the supplied boolean value. out-set: bookings of materials for which the gm attribute does not match the supplied boolean value. If a filter attribute is None or an empty list, its in-set will contain all bookings and its out-set will contain no bookings. If a category is both in included_categories and in excluded_categories, all bookings with this category will be put in the out-set. The in-sets for all filter attributes are combined by intersection to create the filter's in-set. The out-sets are combined by union. The filter's out-set is the complement of its in-set. """ name = models.CharField(verbose_name=_("name"), max_length=150, unique=True) description = models.CharField(verbose_name=_("description"), max_length=250, blank=True) enabled = models.BooleanField(verbose_name=_("Enabled"), default=True) the_order = models.PositiveIntegerField(default=0, editable=False, db_index=True, verbose_name=_("Filter order")) included_categories = TreeManyToManyField( Category, verbose_name=_("included categories"), related_name="+", blank=True, help_text= _("Materials from these categories and their subcategories will be part of the list." ), ) excluded_categories = TreeManyToManyField( Category, verbose_name=_("excluded categories"), related_name="+", blank=True, help_text= _("Materials from these categories and their subcategories will <strong>not</strong> be part of the list." ), ) gm = models.BooleanField( null=True, verbose_name=_("GM"), help_text=_("Setting <em>Unknown</em> disables the condition."), ) class Meta: verbose_name = _("list view filter") verbose_name_plural = _("list view filters") ordering = ["the_order"] def __str__(self): return self.name def filter_bookings(self, bookings): """ Filters the bookings into bookings that satisfy the filters and bookings that do not. :param QuerySet[Booking] bookings: bookings :return Tuple[QuerySet[Booking], QuerySet[Booking]]: included and excluded bookings """ # Remove custom materials that have no material key filters = Q(material__isnull=False) if self.gm is not None: filters &= Q(material__gm=self.gm) if self.included_categories.exists(): filters &= Q(material__categories__in=get_all_subcategories( self.included_categories)) if self.excluded_categories.exists(): filters &= ~Q(material__categories__in=get_all_subcategories( self.excluded_categories)) in_set = bookings.filter(filters).distinct() out_set = bookings.filter(~filters).distinct() return in_set, out_set
class ClassGroup(models.Model): groupname = models.CharField(max_length=50) groupteacher = models.ForeignKey('school.Teacher', on_delete=models.CASCADE, null=True, blank=True) syllabustaught = models.ManyToManyField('tracker.Syllabus') mptt_syllabustaught = TreeManyToManyField('tracker.MPTTSyllabus') archived = models.BooleanField(blank=True, default=False) academic_position = TreeForeignKey('school.AcademicStructure', null=True, on_delete=models.SET_NULL) def __str__(self): return self.groupname def assessments(self): # Avoid a circular import sitting_model = apps.get_model(app_label='tracker', model_name='Sitting') return sitting_model.objects.filter( classgroup=self).order_by('-datesat') def topics(self): # Avoid a circular import SyllabusTopic = apps.get_model(app_label='tracker', model_name='SyllabusTopic') return SyllabusTopic.objects.filter( syllabus__in=self.syllabustaught.all()) def class_topics_w_ratings(self): SyllabusTopic = apps.get_model(app_label='tracker', model_name='SyllabusTopic') topics_taught = SyllabusTopic.objects.filter( syllabus__in=self.syllabustaught.all()) ratings = [] for topic in topics_taught: ratings.append(topic.classAverageRating(self)) data = list(zip(topics_taught, ratings)) return data def class_topics_completion(self): SyllabusTopic = apps.get_model(app_label='tracker', model_name='SyllabusTopic') topics_taught = SyllabusTopic.objects.filter( syllabus__in=self.syllabustaught.all()) completion = [] for topic in topics_taught: completion.append(topic.classAverageCompletion(self)) data = list(zip(topics_taught, completion)) return data def classgroup_average_rating(self): ratings = [] for syllabus in self.syllabustaught.all(): ratings.append(syllabus.classgroup_average_rating(self)) return round(average(ratings), 1) def classgroup_average_completion(self): pcs = [] for syllabus in self.syllabustaught.all(): pcs.append(syllabus.classgroup_completion(self)) return round(average(pcs), 1) def class_topic_all_data(self): SyllabusTopic = apps.get_model(app_label='tracker', model_name='SyllabusTopic') topics_taught = SyllabusTopic.objects.filter( syllabus__in=self.syllabustaught.all()) ratings = [] for topic in topics_taught: ratings.append(topic.classAverageRating(self)) completion = [] for topic in topics_taught: completion.append(topic.classAverageCompletion(self)) data = list(zip(topics_taught, completion, ratings)) return data def students(self): return Student.objects.filter(classgroups=self) def all_students_completion_data(self): students = self.students() ratings = [] journaled = [] for student in students: individual_ratings = [] individual_journaled = [] for syllabus in self.syllabustaught.all(): individual_ratings.append( syllabus.studentAverageRating(student)) individual_journaled.append( syllabus.student_completion(student)) ratings.append(average(individual_ratings)) journaled.append(average(individual_journaled)) data = list(zip(students, journaled, ratings)) return data def percentage_topics_taught(self): # Avoid circular import: SyllabusPoint = apps.get_model(app_label='tracker', model_name='SyllabusPoint') # Get total number of syllabus points total_points = SyllabusPoint.objects.filter( sub_topic__topic__syllabus__in=self.syllabustaught.all()) total_points = total_points.distinct().count() # Find how many individual points we've taught: # Get all lessons: Lesson = apps.get_model(app_label='timetable', model_name='Lesson') all_lessons = Lesson.objects.filter(classgroup=self) taught_points = SyllabusPoint.objects.filter(lesson__in=all_lessons) if taught_points == 0 or total_points == 0: return 0 else: taught_points = taught_points.distinct().count() return round(taught_points / total_points * 100, 0)
class LessonResources(models.Model): lesson = models.ForeignKey(Lesson, blank=True, null=True, on_delete=models.SET_NULL) resource_type = models.CharField(max_length=100, choices=RESOURCE_TYPES, null=True, blank=False) resource_name = models.CharField(max_length=100, null=True, blank=False) link = models.URLField(blank=False, null=True) students_can_view_before = models.BooleanField(default=False) students_can_view_after = models.BooleanField(default=False) available_to_all_classgroups = models.BooleanField(default=False) syllabus_points = models.ManyToManyField(SyllabusPoint, blank=True) mptt_syllabus_points = TreeManyToManyField(MPTTSyllabus) def __str__(self): return self.resource_name def editable_icon(self): """Link to the form to edit a resource """ string = "<a href=" + str( reverse('timetable:edit_lesson_resource', args=[self.lesson.pk, self.pk])) string = string + ' target="_blank" data-toggle="tooltip" data-placement="top" title="' string = string + (str(self.resource_name)) string = string + '">' if self.resource_type == "Presentation": string = string + "<i class='fas fa-desktop'>" elif self.resource_type == "Web Page": string = string + "<i class='fas fa-tablet-alt'>" elif self.resource_type == "Worksheet": string = string + '<i class="fas fa-newspaper">' elif self.resource_type == "Test": string = string + "<i class='fas fa-pencil-ruler'>" elif self.resource_type == "Google Drive": string = string + '<i class="fab fa-google-drive">' else: string = string + '<i class="fas fa-question-circle">' string = string + "</i></a>" return string def icon(self): """ Icon link to the resource itself""" string = "<a href=" + str(self.link) string = string + ' target="_blank" rel="noopener" data-toggle="tooltip" data-placement="top" title="' string = string + (str(self.resource_name)) string = string + '">' if self.resource_type == "Presentation": string = string + "<i class='fas fa-desktop'>" elif self.resource_type == "Web Page": string = string + "<i class='fas fa-tablet-alt'>" elif self.resource_type == "Worksheet": string = string + '<i class="fas fa-newspaper">' elif self.resource_type == "Test": string = string + "<i class='fas fa-pencil-ruler'></i>" elif self.resource_type == "Google Drive": string = string + '<i class="fab fa-google-drive">' else: string = string + '<i class="fas fa-question-circle">' string = string + "</i></a>" return string def student_viewable(self): """ Return True if students should be able to see this resource """ if self.students_can_view_before: return True elif self.students_can_view_after: if self.lesson.date >= datetime.date.today(): return True else: return False def set_syllabus_points(self): if self.lesson: points = self.lesson.mptt_syllabus_points.all().order_by('pk') for point in points: self.mptt_syllabus_points.add(point)
class Lesson(models.Model): lessonslot = models.ForeignKey(TimetabledLesson, on_delete=models.CASCADE) classgroup = models.ForeignKey(ClassGroup, null=True, blank=False, on_delete=models.SET_NULL) status = models.CharField(max_length=20, null=True, blank=True) syllabus_points_covered = models.ManyToManyField(SyllabusPoint, blank=True) lesson_title = models.CharField(max_length=200, null=True, blank=True) description = models.TextField(null=True, blank=True) requirements = models.TextField(null=True, blank=True) homework = models.TextField(null=True, blank=True) homework_due = models.DateField(null=True, blank=True) notes = models.TextField(null=True, blank=True) sequence = models.IntegerField(null=False, blank=True) date = models.DateField(null=True, blank=True) syllabus = models.ForeignKey(Syllabus, blank=True, null=True, on_delete=models.SET_NULL) mptt_syllabus_points = TreeManyToManyField(MPTTSyllabus, blank=True) class Meta: unique_together = (("lessonslot", "date"), ("classgroup", "sequence")) def __str__(self): if self.lesson_title: return str(self.classgroup) + " " + str( self.sequence) + ": " + str(self.lesson_title) else: return str(self.classgroup) + "lesson: " + str( self.sequence) + " " + str(self.date) def resources(self): return LessonResources.objects.filter(lesson=self) def student_viewable_resources(self): # Get the resources set to be viewable at any time all_resources = [] resources = LessonResources.objects.filter( lesson=self, students_can_view_before=True) print(all_resources) for resource in resources: all_resources.append(resource) # If it's been taught, get the 'after' resources: if self.date < datetime.date.today(): resources = LessonResources.objects.filter( lesson=self, students_can_view_after=True).exclude( students_can_view_before=True) for resource in resources: all_resources.append(resource) return all_resources def set_date(self, year): """ A slightly complicated method, which must set the date for the current lesson. We need to create every lesson for the year. 1. Set a start date + period 2. Check if a lesson is suspended 3. If not suspended, get_or_create the lesson, and set it to the date and period 4. Move to next eligible lesson and repeat. """ all_lessons = Lesson.objects.filter( lessonslot__classgroup=self.lessonslot.classgroup).order_by( 'sequence') # Lesson slots where these appear. slots = TimetabledLesson.objects.filter( classgroup=self.lessonslot.classgroup) # Find total lessons per week lessons_per_week = int( TimetabledLesson.objects.filter( classgroup=self.lessonslot.classgroup).count()) # we'll use *week* to track each week we're looking at. global week, lesson_of_week, slot_number, current_lesson week = 0 lesson_of_week = 0 slot_number = 0 current_lesson = 0 # Set our starting lesson date: dow = slots[0].lesson_slot.dow() date = CALENDAR_START_DATE[year] + datetime.timedelta(days=dow) days_taught = [] for slot in slots: days_taught.append(slot.lesson_slot.dow()) def next_lesson(week, lesson_of_week, slot_number): if lesson_of_week == ( lessons_per_week - 1): # We just did the last lesson of the week week = week + 1 lesson_of_week = 0 else: lesson_of_week = lesson_of_week + 1 if slot_number != lessons_per_week - 1: slot_number = slot_number + 1 else: slot_number = 0 date = CALENDAR_START_DATE + datetime.timedelta( days=days_taught[slot_number], weeks=week) return week, lesson_of_week, slot_number, date while date < CALENDAR_END_DATE[year]: # Iteratete this over the slots: for slot in slots: if check_suspension(date, slot.lesson_slot.period, slot.classgroup): # lesson has been suspended week, lesson_of_week, slot_number, date = next_lesson( week, lesson_of_week, slot_number) continue else: # lesson is not suspended lesson, created = Lesson.objects.get_or_create( date=date, lessonslot=slots[slot_number], classgroup=slots[slot_number].classgroup) # lesson.sequence = current_lesson # current_lesson = current_lesson + 1 week, lesson_of_week, slot_number, date = next_lesson( week, lesson_of_week, slot_number) lesson.save # def save(self, *args, **kwargs): # # super(Lesson, self).save(*args, **kwargs) # # return self def lesson_resource_icons(self): icons = [] resources = LessonResources.objects.filter(lesson=self) for resource in resources: icons.append(resource.icon) return icons def delete(self, *args, **kwargs): # We've removed a lesson, so we need to decerement all the following lessons following_lessons = Lesson.objects.filter( classgroup=self.classgroup, sequence__gt=self.sequence).order_by('sequence') # Avoid integrity error: # Find max sequence max = following_lessons.aggregate(Max('sequence')) if max['sequence__max'] is not None: self.sequence = max['sequence__max'] + 10 self.save() for lesson in following_lessons: lesson.sequence = lesson.sequence - 1 lesson.save() super().delete(*args, **kwargs) def homework_due_lessons(self): lessons_w_homework_due = Lesson.objects.filter( homework_due=self.date, classgroup=self.classgroup) if lessons_w_homework_due.count(): return lessons_w_homework_due else: return False def next_in_order(self): return Lesson.objects.get(classgroup=self.classgroup, sequence=self.sequence + 1)
class Task(MPTTModel): """ Task model """ STATUS_DECLINE = 0 STATUS_DRAFT = 1 STATUS_PENDING = 2 STATUS_WORKING = 3 STATUS_HALF_DONE = 4 STATUS_ALMOST_DONE = 5 STATUS_COMPLETE = 6 STATUS_APPROVE = 7 STATUS_CHOICES = ( (STATUS_DECLINE, 'Declined'), (STATUS_DRAFT, 'Draft'), (STATUS_PENDING, 'Pending Acceptance'), (STATUS_WORKING, 'Working On It'), (STATUS_HALF_DONE, 'Half Way Done'), (STATUS_ALMOST_DONE, 'Almost Done'), (STATUS_COMPLETE, 'Completed'), (STATUS_APPROVE, 'Approve'), ) CRITICALITY_LOW = 0 CRITICALITY_MEDIUM = 1 CRITICALITY_HIGH = 2 CRITICALITY_CHOICES = ( (CRITICALITY_HIGH, 'High'), (CRITICALITY_MEDIUM, 'Medium'), (CRITICALITY_LOW, 'Low'), ) parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) title = models.CharField('Title', max_length=4096) description = models.TextField('Description') creator = models.ForeignKey(User, verbose_name='Creator', related_name='created_tasks') owner = models.ForeignKey(User, verbose_name='Owner', related_name='owned_tasks', blank=True, null=True) owners = TreeManyToManyField( User, verbose_name='Owners', through='TaskAssignedUser', blank=True, ) status = models.SmallIntegerField('Status', choices=STATUS_CHOICES, default=STATUS_DRAFT) status_description = models.TextField('Status description') criticality = models.SmallIntegerField('Criticality', choices=CRITICALITY_CHOICES, default=CRITICALITY_MEDIUM) date_due = models.DateField('Due date', blank=True, null=True) time_create = models.DateTimeField('Time of create', auto_now_add=True) time_update = models.DateTimeField('Time of update', auto_now=True) def get_absolute_url(self): return reverse('task_management:detail', kwargs={'pk': self.pk}) def owner_accept_task(self): """ Owner is accepted task :return: boolean """ return TaskAssignedUser.objects.filter( task=self).order_by('time_assign').last().assign_accept def get_owners_chain(self, assign_accept=None): """ Get chain of assignment users :param assign_accept: :return: list of assignment users """ owner_chain = TaskAssignedUser.objects.filter( task=self).order_by('time_assign').select_related('user') if assign_accept: owner_chain = owner_chain.filter(assign_accept=assign_accept) return [obj.user for obj in owner_chain] def get_accepted_owners_chain(self): """ Get owners which accepted task :return: list of assignment users """ return self.get_owners_chain(assign_accept=True) @staticmethod def is_status_can_change(status): """ Check whether it is possible to change the status :param status: task status :return: boolean """ return Task.STATUS_PENDING < status < Task.STATUS_APPROVE def __str__(self): return self.title
class Promotion(models.Model): category = TreeManyToManyField(Category, blank=True, symmetrical=False, related_name='promotions', verbose_name='Категория') # category = TreeForeignKey(Genre, blank=True, null=True, default=None, on_delete=models.CASCADE, related_name='promotions', verbose_name='Категория') name = models.CharField(blank=True, null=True, default=None, max_length=200, verbose_name='Название рекламодателя') slug = models.SlugField(null=True, blank=True, max_length=200, db_index=True, verbose_name='Nazvanie_reklamodatelya') country = models.CharField(blank=True, null=True, default='Россия', max_length=200, verbose_name='Страна') region = models.CharField(blank=True, null=True, default='Курская область', max_length=200, verbose_name='Регион') town = models.CharField(blank=True, null=True, default='Курск', max_length=200, verbose_name='Город') site = models.URLField(max_length=1024, blank=True, default=None, null=None, verbose_name='Сайт') email = models.EmailField(max_length=128, blank=True, null=True, default=None, verbose_name='Емейл') photo = models.ImageField(upload_to='promotions_test_photos/%Y/%m/%d', blank=True, verbose_name='Фото') logotype = models.ImageField( upload_to='promotions_test_logotypes/%Y/%m/%d', blank=True, verbose_name='Логотип') description = models.TextField(max_length=512, blank=True, verbose_name='Описание деятельности') is_active = models.BooleanField(default=False, verbose_name='Активность рекламы') paid = models.BooleanField(default=False, verbose_name='Оплачен показ рекламы?') created = models.DateField(blank=True, null=True, default=timezone.now, verbose_name='Дата создания записи') updated = models.DateField(blank=True, null=True, default=timezone.now, verbose_name='Дата ред-ия записи') class Meta: ordering = ('-created', 'name') index_together = (('id', 'slug'), ) verbose_name = 'Место под рекламу' verbose_name_plural = 'Места под рекламу' def __str__(self): return '%s' % self.name def get_absolute_url(self): return reverse('reclame:promotion_detail', args=[self.id, self.slug])