def get(self, request): start = self.request.query_params.get('start', None) end = self.request.query_params.get('end', None) # Validation if start is None and end is None: return Response({'error': 'date not provide'}, status=status.HTTP_400_BAD_REQUEST) start = parse_date(start) end = parse_date(end) if start is None and end is None: return Response({'error': 'date incorrect'}, status=status.HTTP_400_BAD_REQUEST) # Coworking Space query_coworking = Payment.objects.filter( date_created__date__gte=start, date_created__date__lte=end, coworkingspacesubscription__isnull=False) group_coworking = query_coworking.annotate( date=TruncDay('date_created', output_field=DateField())) \ .values('date').annotate(count=Count('id'), amount=Sum('amount')) stat_coworking = [] coworkingspace_sale = 0 for result in group_coworking: stat_coworking.append(result) coworkingspace_sale += result['amount'] # Meeting Room query_meetingroom = Payment.objects.filter( date_created__date__gte=start, date_created__date__lte=end, meetingroombooking__isnull=False) group_meetingroom = query_meetingroom.annotate( date=TruncDay('date_created', output_field=DateField())) \ .values('date').annotate(count=Count('id'), amount=Sum('amount')) stat_meetingroom = [] meetingroom_sale = 0 for result in group_meetingroom: stat_meetingroom.append(result) meetingroom_sale += result['amount'] # Payment Method query_method = Payment.objects.filter(date_created__date__gte=start, date_created__date__lte=end) group_method = query_method.values('method').annotate( count=Count('id'), amount=Sum('amount')) payment_method = [] for result in group_method: payment_method.append(result) # Customer query_customer = User.objects.filter(date_joined__date__lte=end) customer_all = query_customer.count() customer_new = query_customer.filter( date_joined__date__gte=start).count() customer_old = customer_all - customer_new return Response({ 'total_sale': coworkingspace_sale + meetingroom_sale, 'coworkingspace_sale': coworkingspace_sale, 'meetingroom_sale': meetingroom_sale, 'coworkingspace_sale_by_date': stat_coworking, 'meetingroom_sale_by_date': stat_meetingroom, 'payment_method': payment_method, 'customer_all': customer_all, 'customer_new': customer_new, 'customer_old': customer_old })
class Event(Page): resource_type = 'event' parent_page_types = ['events.Events'] subpage_types = [] template = 'event.html' # Content fields description = TextField(max_length=250, blank=True, default='') image = ForeignKey('mozimages.MozImage', null=True, blank=True, on_delete=SET_NULL, related_name='+') body = CustomStreamField(blank=True, null=True) agenda = StreamField(StreamBlock([ ('agenda_item', AgendaItemBlock()), ], required=False), blank=True, null=True) speakers = StreamField(StreamBlock([ ('speaker', PageChooserBlock(required=False, target_model='people.Person')), ('external_speaker', ExternalSpeakerBlock(required=False)), ], required=False), blank=True, null=True) # Card fields card_title = CharField('Title', max_length=140, blank=True, default='') card_description = TextField('Description', max_length=140, blank=True, default='') card_image = ForeignKey( 'mozimages.MozImage', null=True, blank=True, on_delete=SET_NULL, related_name='+', verbose_name='Image', ) # Meta fields start_date = DateField(default=datetime.date.today) end_date = DateField(blank=True, null=True) latitude = FloatField(blank=True, null=True) longitude = FloatField(blank=True, null=True) register_url = URLField('Register URL', blank=True, null=True) venue_name = CharField(max_length=100, blank=True, default='', help_text='') venue_url = URLField('Venue URL', max_length=100, blank=True, default='', help_text='') address_line_1 = CharField(max_length=100, blank=True, default='', help_text='') address_line_2 = CharField(max_length=100, blank=True, default='', help_text='') address_line_3 = CharField(max_length=100, blank=True, default='', help_text='') city = CharField(max_length=100, blank=True, default='', help_text='') state = CharField('State/Province/Region', max_length=100, blank=True, default='', help_text='') zip_code = CharField('Zip/Postal code', max_length=100, blank=True, default='', help_text='') country = CountryField(blank=True, default='', help_text='') keywords = ClusterTaggableManager(through=EventTag, blank=True) # Content panels content_panels = Page.content_panels + [ FieldPanel('description'), ImageChooserPanel('image'), StreamFieldPanel('body'), StreamFieldPanel('agenda'), StreamFieldPanel('speakers'), ] # Card panels card_panels = [ FieldPanel('card_title'), FieldPanel('card_description'), ImageChooserPanel('card_image'), ] # Meta panels meta_panels = [ MultiFieldPanel( [ FieldPanel('start_date'), FieldPanel('end_date'), FieldPanel('latitude'), FieldPanel('longitude'), FieldPanel('register_url'), ], heading='Event details', classname='collapsible', ), MultiFieldPanel( [ FieldPanel('venue_name'), FieldPanel('venue_url'), FieldPanel('address_line_1'), FieldPanel('address_line_2'), FieldPanel('address_line_3'), FieldPanel('city'), FieldPanel('state'), FieldPanel('zip_code'), FieldPanel('country'), ], heading='Event address', classname='collapsible', ), MultiFieldPanel( [ InlinePanel('topics'), ], heading='Topics', help_text= ('These are the topic pages the article will appear on. The first ' 'topic in the list will be treated as the primary topic.')), MultiFieldPanel([ FieldPanel('seo_title'), FieldPanel('search_description'), FieldPanel('keywords'), ], heading='SEO'), ] # Settings panels settings_panels = [ FieldPanel('slug'), ] edit_handler = TabbedInterface([ ObjectList(content_panels, heading='Content'), ObjectList(card_panels, heading='Card'), ObjectList(meta_panels, heading='Meta'), ObjectList(settings_panels, heading='Settings', classname='settings'), ]) @property def is_upcoming(self): """Returns whether an event is in the future.""" return self.start_date > datetime.date.today() @property def primary_topic(self): """Return the first (primary) topic specified for the event.""" article_topic = self.topics.first() return article_topic.topic if article_topic else None @property def month_group(self): return self.start_date.replace(day=1) @property def event_dates(self): """Return a formatted string of the event start and end dates""" event_dates = self.start_date.strftime("%b %-d") if self.end_date: event_dates += " – " start_month = self.start_date.strftime("%m") if self.end_date.strftime("%m") == start_month: event_dates += self.end_date.strftime("%-d") else: event_dates += self.end_date.strftime("%b %-d") return event_dates @property def event_dates_full(self): """Return a formatted string of the event start and end dates, including the year""" return self.event_dates + self.start_date.strftime(", %Y") def has_speaker(self, person): for speaker in self.speakers: if (speaker.block_type == 'speaker' and str(speaker.value) == str(person.title)): return True return False
class Survey(Model): """ read_only: Keep original data(read_only=True). Modify data(read_only=False). new field second and non_second table 1.4 """ farmer_id = CharField(max_length=12, verbose_name=_("Farmer Id"), db_index=True) farmer_name = CharField(null=True, blank=True, max_length=30, verbose_name=_("Name")) interviewee_relationship = CharField( null=True, blank=True, max_length=30, verbose_name=_("Interviewee Relationship")) total_pages = IntegerField(verbose_name=_("Total Pages")) page = IntegerField(verbose_name=_("Page")) origin_class = IntegerField(null=True, blank=True, verbose_name=_("Origin Class")) second = BooleanField(default=False, verbose_name=_("Second")) non_second = BooleanField(default=False, verbose_name=_("Non Second")) main_income_source = BooleanField(default=False, verbose_name=_("Main Income Source")) non_main_income_source = BooleanField( default=False, verbose_name=_("Non Main Income Source")) known_subsidy = BooleanField(default=False, verbose_name=_("Known Subsidy")) non_known_subsidy = BooleanField(default=False, verbose_name=_("Non Known Subsidy")) hire = BooleanField(default=False, verbose_name=_("Hire")) non_hire = BooleanField(default=False, verbose_name=_("Non Hire")) lacks = ManyToManyField("surveys22.Lack", blank=True, related_name="surveys", verbose_name=_("Lack")) management_types = ManyToManyField( "surveys22.ManagementType", blank=True, related_name="surveys", verbose_name=_("Management Types"), ) note = TextField(null=True, blank=True, verbose_name=_("Note")) readonly = BooleanField(default=True, verbose_name=_("Read Only")) investigator = CharField(null=True, blank=True, max_length=10, verbose_name=_("Investigator")) reviewer = CharField(null=True, blank=True, max_length=10, verbose_name=_("Reviewer")) date = DateField(null=True, blank=True, verbose_name=_("Investigation Date")) distance = IntegerField(null=True, blank=True, verbose_name=_("Investigation Distance(km)")) period = IntegerField(null=True, blank=True, verbose_name=_("Investigation Period")) update_time = DateTimeField( auto_now=True, auto_now_add=False, null=True, blank=True, verbose_name=_("Updated"), ) review_logs = GenericRelation(ReviewLog, related_query_name="surveys22") class Meta: verbose_name = _("Survey") verbose_name_plural = _("Survey") def __str__(self): return self.farmer_id
class Semester(Model): """ График учебного процесса """ AUTUMN = 'AUT' SPRING = 'SPR' SEMESTER = ((AUTUMN, 'осень'), (SPRING, 'весна')) student_group = ForeignKey('StudentGroup', on_delete=CASCADE, verbose_name='учебная группа') year = IntegerField('календарный год') semester = CharField('семестр', max_length=3, choices=SEMESTER) begin_study = DateField('начало теоретического обучения', blank=True, null=True) end_study = DateField('конец теоретического обучения', blank=True, null=True) begin_exams = DateField('начало экзаменационной сессии', blank=True, null=True) end_exams = DateField('конец экзаменационной сессии', blank=True, null=True) class Meta: verbose_name = 'семестр' verbose_name_plural = 'график учебного процесса' def __str__(self): begin = self.year end = self.year + 1 if self.semester == Semester.SPRING: begin = self.year - 1 end = self.year return '%s: %d-%d, %s' % (self.student_group.name, begin, end, self.get_semester_display()) def get_study_period(self): """ Период обучения """ if self.begin_study is None or self.end_study is None: return "" else: return '%s – %s' % (self.begin_study.strftime('%Y.%m.%d'), self.end_study.strftime('%Y.%m.%d')) get_study_period.short_description = "Период обучения" def get_exams_period(self): """ Сессия """ if self.begin_exams is None or self.end_exams is None: return "" else: return '%s – %s' % (self.begin_exams.strftime('%Y.%m.%d'), self.end_exams.strftime('%Y.%m.%d')) get_exams_period.short_description = "Сессия" def get_semester(self): begin = self.year end = self.year + 1 if self.semester == Semester.SPRING: begin = self.year - 1 end = self.year return '%d-%d уч.г., %s' % (begin, end, self.get_semester_display()) def get_year_display(self): begin = self.year end = self.year + 1 if self.semester == Semester.SPRING: begin = self.year - 1 end = self.year return '%d-%d учебный год' % (begin, end)
class StrainSource(Model): """ A strain source contains all the meta-data relating to where a strain was collected from whom, by whom, and what ever else we can say about the strain. """ name = CharField(max_length=128, db_index=True, unique=True) old_id = CharField(max_length=50, db_index=True, null=True, blank=True) cluster = CharField(max_length=15, null=True, blank=True) date = DateField(null=True, blank=True) country = ForeignKey(Country, null=True, blank=True, related_name='sources') city = ForeignKey(Place, null=True, blank=True, related_name='sources') importer = ForeignKey(ImportSource, verbose_name='Import Source', null=True, blank=True) source_lab = CharField(max_length=100, verbose_name='Laboratory Source', db_index=True, null=True, blank=True) source_paper = ForeignKey(Paper, related_name="strains", null=True, blank=True) bioproject = ForeignKey(BioProject, related_name="strains", null=True, blank=True) patient_id = CharField(max_length=16, db_index=True) patient_age = PositiveIntegerField(null=True, blank=True) patient_sex = CharField(max_length=3, choices=SEXES, null=True, blank=True) patient_hiv = CharField(max_length=10, choices=HIVS, null=True, blank=True) spoligotype_type = IntegerField(null=True, blank=True) spoligotype_family = CharField("Spoligotype Family Parent Strain", max_length=255, null=True, blank=True) spoligotype_octal = CharField(validators=[is_octal], max_length=15, null=True, blank=True) lineage = ForeignKey(Lineage, related_name='strains', null=True, blank=True) rflp_type = CharField("Restriction fragment length polymorphism type", max_length=10, null=True, blank=True) rflp_family = CharField("Restriction fragment length polymorphism family", max_length=10, null=True, blank=True) insert_type = IntegerField("Insertion sequence 6110 type", null=True, blank=True) wgs_group = CharField("Whole Genome Sequence Group", max_length=10, null=True, blank=True) principle_group = IntegerField("Principle Generic Group", null=True, blank=True) resistance_group = CharField(max_length=4, choices=RESISTANCE_GROUP, null=True, blank=True) targeting = ForeignKey(TargetSet, null=True, blank=True) notes = TextField(null=True, blank=True) objects = StrainSourceManager() def natural_key(self): """Natural key for strains based just on their name""" return (self.name, ) def generate_resistance_group(self): """Generates the correct resistance_group based on drug information""" resistant_to = self.drugs.filter(resistance='r').values_list( 'drug__code', flat=True) sensitive_to = self.drugs.filter(resistance='s').values_list( 'drug__code', flat=True) group = None # Unknown if 'INH' in resistant_to and 'RIF' in resistant_to: group = 'MDR' if ('MOXI' in resistant_to) or ('GATI' in resistant_to) or ( 'LEVO' in resistant_to): if ('KAN' in resistant_to) or ('AMK' in resistant_to) or ( 'CAP' in resistant_to): group = 'XDR' elif resistant_to: group = 'ODR' elif 'INH' in sensitive_to or 'RIF' in sensitive_to: group = 's' self.resistance_group = group self.save() def __str__(self): return self.name or self.patient_id or ("Unnamed %d" % self.pk)
class ModelWithUniqueSlugYear(Model): date = DateField() slug = AutoSlugField(unique_with='date__year')
class Question(Model): question_text = CharField(max_length=200, unique=True) pub_date = DateField('Publish Date') def __str__(self): return self.question_text
class EquipmentInstanceProblemDiagnosis(Model): """Equipment Instance Problem Diagnosis.""" RELATED_NAME = 'equipment_instance_problem_diagnoses' RELATED_QUERY_NAME = 'equipment_instance_problem_diagnosis' equipment_instance = \ ForeignKey( to=EquipmentInstance, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) from_date = \ DateField( blank=False, null=False, db_index=True) to_date = \ DateField( blank=True, null=True, db_index=True) date_range = \ DateRangeField( blank=True, null=True) duration = \ IntegerField( blank=True, null=True) equipment_problem_types = \ ManyToManyField( to=EquipmentProblemType, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=True) has_equipment_problems = \ BooleanField( blank=False, null=False, default=False, db_index=True) dismissed = \ BooleanField( blank=False, null=False, default=False, db_index=True) comments = \ TextField( blank=True, null=True) equipment_instance_alarm_periods = \ ManyToManyField( to=EquipmentInstanceAlarmPeriod, through=(EquipmentInstanceAlarmPeriod .equipment_instance_problem_diagnoses.through), related_name=RELATED_NAME + '_reverse', related_query_name=RELATED_QUERY_NAME, blank=True) has_associated_equipment_instance_alarm_periods = \ BooleanField( blank=False, null=False, default=False, db_index=True) equipment_instance_alert_periods = \ ManyToManyField( to='EquipmentInstanceAlertPeriod', related_name=RELATED_NAME + '_reverse', related_query_name=RELATED_QUERY_NAME, blank=True) has_associated_equipment_instance_alert_periods = \ BooleanField( blank=False, null=False, default=False, db_index=True) class Meta: """Metadata.""" verbose_name = 'Equipment Instance Problem Diagnosis' verbose_name_plural = 'Equipment Instance Problem Diagnoses' unique_together = 'equipment_instance', 'from_date' ordering = 'dismissed', '-to_date', 'from_date' def __str__(self): """Return string repr.""" return (f'{self.equipment_instance} from {self.from_date} ' + (f'to {self.to_date}' if self.to_date else '(ONGOING)') + ( ': {}'.format( # pylint: disable=consider-using-f-string ', '.join(equipment_problem_type.name.upper() for equipment_problem_type in self.equipment_problem_types.all())) if self.equipment_problem_types.count() else '') + (' (DISMISSED)' if self.dismissed else '')) def save(self, *args, **kwargs): """Save.""" self.date_range = \ DateRange( lower=self.from_date, upper=self.to_date, bounds='[]', empty=False) self.duration = \ (self.to_date - self.from_date).days + 1 \ if self.to_date \ else None super().save(*args, **kwargs)
class EquipmentInstanceAlertPeriod(Model): """Equipment Instance Alert Period.""" RELATED_NAME = 'equipment_instance_alert_periods' RELATED_QUERY_NAME = 'equipment_instance_alert_period' equipment_unique_type_group = \ ForeignKey( to=EquipmentUniqueTypeGroup, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) equipment_instance = \ ForeignKey( to=EquipmentInstance, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) risk_score_name = \ CharField( max_length=MAX_CHAR_LEN, blank=False, null=False, unique=False, db_index=True) threshold = \ FloatField( blank=False, null=False, default=0, db_index=True) from_date = \ DateField( blank=False, null=False, auto_now=False, auto_created=False, default=None, db_index=True) to_date = \ DateField( blank=False, null=False, auto_now=False, auto_created=False, default=None, db_index=True) date_range = \ DateRangeField( blank=True, null=True) duration = \ IntegerField( blank=False, null=False, default=0) cumulative_excess_risk_score = \ FloatField( blank=False, null=False, default=0) approx_average_risk_score = \ FloatField( blank=False, null=False, default=0) last_risk_score = \ FloatField( blank=False, null=False, default=0) ongoing = \ BooleanField( blank=False, null=False, default=False, db_index=True) info = \ JSONField( blank=True, null=True, default=dict) diagnosis_status = \ ForeignKey( to=AlertDiagnosisStatus, blank=True, null=True, on_delete=PROTECT) equipment_instance_alarm_periods = \ ManyToManyField( to=EquipmentInstanceAlarmPeriod, through=(EquipmentInstanceAlarmPeriod .equipment_instance_alert_periods.through), related_name=RELATED_NAME + '_reverse', related_query_name=RELATED_QUERY_NAME, blank=True) has_associated_equipment_instance_alarm_periods = \ BooleanField( blank=False, null=False, default=False, db_index=True) equipment_instance_problem_diagnoses = \ ManyToManyField( to=EquipmentInstanceProblemDiagnosis, through=(EquipmentInstanceProblemDiagnosis .equipment_instance_alert_periods.through), related_name=RELATED_NAME + '_reverse', related_query_name=RELATED_QUERY_NAME, blank=True) has_associated_equipment_instance_problem_diagnoses = \ BooleanField( blank=False, null=False, default=False, db_index=True) class Meta: """Metadata.""" verbose_name = 'Equipment Instance Alert Period' verbose_name_plural = 'Equipment Instance Alert Periods' unique_together = \ ('equipment_unique_type_group', 'equipment_instance', 'risk_score_name', 'threshold', 'from_date'), \ ('equipment_unique_type_group', 'equipment_instance', 'risk_score_name', 'threshold', 'to_date') ordering = \ 'diagnosis_status', \ '-ongoing', \ 'risk_score_name', \ '-threshold', \ '-cumulative_excess_risk_score' def __str__(self): """Return string repr.""" if self.diagnosis_status is None: self.save() return (f'{self.diagnosis_status.name.upper()}: ' + ( 'ONGOING ' if self.ongoing else '' ) + 'Alert on ' + ( f'{self.equipment_unique_type_group.equipment_general_type.name.upper()} ' # noqa: E501 f'{self.equipment_unique_type_group.name} ' f'#{self.equipment_instance.name} ' f'from {self.from_date} to {self.to_date} ' f'w Approx Avg Risk Score {self.approx_average_risk_score:,.1f} ' f'(Last: {self.last_risk_score:,.1f}) ' f'(based on {self.risk_score_name} > {self.threshold}) ' f'for {self.duration:,} Day(s)')) def save(self, *args, **kwargs): """Save.""" self.date_range = \ DateRange( lower=self.from_date, upper=self.to_date, bounds='[]', empty=False) self.duration = duration = \ (self.to_date - self.from_date).days + 1 self.approx_average_risk_score = \ self.threshold + \ (self.cumulative_excess_risk_score / duration) if self.diagnosis_status is None: self.diagnosis_status = \ AlertDiagnosisStatus.objects.get_or_create(index=0)[0] super().save(*args, **kwargs)
class EquipmentInstanceDailyPredictedFault(Model): """Equipment Instance Daily Predicted Fault.""" RELATED_NAME = 'equipment_instance_daily_predicted_faults' RELATED_QUERY_NAME = 'equipment_instance_daily_predicted_fault' id = BigAutoField(primary_key=True) equipment_unique_type_group = \ ForeignKey( verbose_name='Equipment Unique Type Group', help_text='Equipment Unique Type Group', to=EquipmentUniqueTypeGroup, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) equipment_instance = \ ForeignKey( verbose_name='Equipment Instance', help_text='Equipment Instance', to=EquipmentInstance, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) date = \ DateField( verbose_name='Date', help_text='Date', blank=False, null=False, db_index=True) fault_type = \ ForeignKey( verbose_name='Fault Type', help_text='Fault Type', to=EquipmentProblemType, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) fault_predictor_name = \ CharField( verbose_name='Fault Predictor Name', help_text='Fault Predictor Name', max_length=MAX_CHAR_LEN, blank=False, null=False, db_index=True) predicted_fault_probability = \ FloatField( verbose_name='Predicted Fault Probability', help_text='Predicted Fault Probability', blank=False, null=False) class Meta: """Metadata.""" verbose_name = 'Equipment Instance Daily Predicted Fault' verbose_name_plural = 'Equipment Instance Daily Predicted Faults' constraints = (UniqueConstraint( fields=('equipment_unique_type_group', 'equipment_instance', 'date', 'fault_type', 'fault_predictor_name'), name='EquipmentInstanceDailyPredictedFault_unique_together'), ) def __str__(self): """Return string repr.""" return ( f'{self.equipment_unique_type_group.equipment_general_type.name} ' # noqa: E501 f'{self.equipment_unique_type_group.name} ' f'#{self.equipment_instance.name} on {self.date}: ' f'{self.fault_type.name.upper()} predicted ' f'w/ prob {100 * self.predicted_fault_probability:.1f}% ' f'by {self.fault_predictor_name}')
class EquipmentInstanceDailyRiskScore(Model): """Equipment Instance Daily Risk Score.""" RELATED_NAME = 'equipment_instance_daily_risk_scores' RELATED_QUERY_NAME = 'equipment_instance_daily_risk_score' id = BigAutoField(primary_key=True) equipment_unique_type_group = \ ForeignKey( to=EquipmentUniqueTypeGroup, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) equipment_instance = \ ForeignKey( to=EquipmentInstance, related_name=RELATED_NAME, related_query_name=RELATED_QUERY_NAME, blank=False, null=False, on_delete=PROTECT) risk_score_name = \ CharField( blank=False, null=False, db_index=True, max_length=MAX_CHAR_LEN) date = \ DateField( blank=False, null=False, db_index=True) risk_score_value = \ FloatField( blank=False, null=False) class Meta: """Metadata.""" verbose_name = 'Equipment Instance Daily Risk Score' verbose_name_plural = 'Equipment Instance Daily Risk Scores' unique_together = \ 'equipment_unique_type_group', \ 'equipment_instance', \ 'risk_score_name', \ 'date' def __str__(self): """Return string repr.""" return ( f'{self.equipment_unique_type_group.equipment_general_type.name} ' # noqa: E501 f'{self.equipment_unique_type_group.name} ' f'#{self.equipment_instance.name} on {self.date}: ' f'{self.risk_score_name} = {self.risk_score_value:.3g}')
def test_trunc_time_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321000)) end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123000)) if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime, is_dst=False) end_datetime = timezone.make_aware(end_datetime, is_dst=False) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) self.assertQuerysetEqual( DTModel.objects.annotate(extracted=TruncTime('start_datetime')).order_by('start_datetime'), [ (start_datetime.time()), (end_datetime.time()), ], lambda m: (m.extracted) ) self.assertEqual(DTModel.objects.filter(start_datetime__time=TruncTime('start_datetime')).count(), 2) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to TimeField"): list(DTModel.objects.annotate(truncated=TruncTime('start_date'))) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to TimeField"): list(DTModel.objects.annotate(truncated=TruncTime('start_date', output_field=DateField())))
def test_trunc_func(self): start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321)) end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)) if settings.USE_TZ: start_datetime = timezone.make_aware(start_datetime, is_dst=False) end_datetime = timezone.make_aware(end_datetime, is_dst=False) self.create_model(start_datetime, end_datetime) self.create_model(end_datetime, start_datetime) msg = 'output_field must be either DateField, TimeField, or DateTimeField' with self.assertRaisesMessage(ValueError, msg): list(DTModel.objects.annotate(truncated=Trunc('start_datetime', 'year', output_field=IntegerField()))) with self.assertRaisesMessage(AssertionError, "'name' isn't a DateField, TimeField, or DateTimeField."): list(DTModel.objects.annotate(truncated=Trunc('name', 'year', output_field=DateTimeField()))) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_date', 'second'))) with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_time', 'month'))) with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_date', 'month', output_field=DateTimeField()))) with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"): list(DTModel.objects.annotate(truncated=Trunc('start_time', 'second', output_field=DateTimeField()))) def test_datetime_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc('start_datetime', kind, output_field=DateTimeField()) ).order_by('start_datetime'), [ (truncate_to(start_datetime, kind)), (truncate_to(end_datetime, kind)) ], lambda m: (m.truncated) ) def test_date_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc('start_date', kind, output_field=DateField()) ).order_by('start_datetime'), [ (truncate_to(start_datetime.date(), kind)), (truncate_to(end_datetime.date(), kind)) ], lambda m: (m.truncated) ) def test_time_kind(kind): self.assertQuerysetEqual( DTModel.objects.annotate( truncated=Trunc('start_time', kind, output_field=TimeField()) ).order_by('start_datetime'), [ (truncate_to(start_datetime.time(), kind)), (truncate_to(end_datetime.time(), kind)) ], lambda m: (m.truncated) ) test_date_kind('year') test_date_kind('month') test_date_kind('day') test_time_kind('hour') test_time_kind('minute') test_time_kind('second') test_datetime_kind('year') test_datetime_kind('month') test_datetime_kind('day') test_datetime_kind('hour') test_datetime_kind('minute') test_datetime_kind('second') qs = DTModel.objects.filter(start_datetime__date=Trunc('start_datetime', 'day', output_field=DateField())) self.assertEqual(qs.count(), 2)
class Person(BaseModelMixin): first_name = CharField('Имя', max_length=50) last_name = CharField('Фамилия', max_length=50) middle_name = CharField('Отчество', max_length=50, default='', blank=True) birth_date = DateField('Дата рождения', null=True, blank=True) user = OneToOneField(User, verbose_name='Пользователь', on_delete=PROTECT, related_name='person', null=True, blank=True) passport_number = CharField('Паспорт', max_length=10, null=True, blank=True, unique=True) passport_date = DateField('Дата выдачи паспорта', null=True, blank=True) phone = CharField('Телефон', max_length=15, null=True, blank=True) WORKED = 'worked' FIRED = 'fired' CANDIDATE = 'candidate' REFUSED = 'refused' APPROVED = 'approved' RESERVE = 'reserve' STATUSES = ( (WORKED, 'Работает'), (FIRED, 'Уволен'), (CANDIDATE, 'Кандидат'), (REFUSED, 'Отклонен'), (APPROVED, 'Проверен'), (RESERVE, 'В резерве'), ) status = CharField('Статус', choices=STATUSES, max_length=10, null=True, blank=True) station = ForeignKey('Station', verbose_name='Станция', on_delete=PROTECT, related_name='persons', null=True, blank=True) def save_to_path(self, filename): valid_extensions = [ 'pdf', ] ext = filename.rsplit('.', 1)[1] if ext.lower() in valid_extensions: raise ValidationError('Unsupported file extension.') return f'documents/{self.passport_number.lower()}.{ext}' document_file = FileField(upload_to=save_to_path, verbose_name='Файл документа', null=True, blank=True) @property def full_name(self): return f'{self.first_name} {self.last_name} {self.middle_name}'.strip() @property def short_name(self): return f'{self.first_name} {self.last_name[0]}.' def __str__(self): return f"{self.full_name} ({self.passport_number})" class Meta: verbose_name = _('Персона') verbose_name_plural = _('Персоны')
class ModelWithUniqueSlugDay(Model): # same as ...Date, just more explicit date = DateField() slug = AutoSlugField(unique_with='date__day')
class Quote(Model): IN_PROGRESS = 'in_progress' SENT_TO_JUNIPER = 'sent_to_juniper' JUNIPER_QUOTE_UPLOADED = 'juniper_quote_uploaded' JUNIPER_QUOTE_VERIFIED = 'juniper_quote_verified' SENT_TO_DISTRIBUTOR = 'sent_to_distributor' COMPLETE = 'complete' QUOTE_STATUS = ( (IN_PROGRESS, 'In Progress'), (SENT_TO_JUNIPER, 'Quote Sent to Juniper'), (JUNIPER_QUOTE_UPLOADED, 'Juniper Quote Uploaded'), (JUNIPER_QUOTE_VERIFIED, 'Juniper Quote Verified'), (SENT_TO_DISTRIBUTOR, 'Quote Sent to Distributor'), (COMPLETE, 'Complete/Uploaded'), ) name = CharField(max_length=255) status = CharField(max_length=255, choices=QUOTE_STATUS, default=IN_PROGRESS) opportunity = ForeignKey('Opportunity', related_name='quotes') price_list = ForeignKey('PriceList', related_name='quotes') date_created = DateTimeField(auto_now_add=True) last_modified = DateTimeField(auto_now=True) expiration_date = DateField() customer_approved = BooleanField(default=True) version = PositiveIntegerField(default=1) # Numbers to track the quotes. Tracking number is automatically set, while # the reference number is manual and set by the user. tracking_number = CharField(max_length=255, default=uuid4) reference_number = CharField(max_length=255, null=True, blank=True) def __unicode__(self): return self.name def save(self, *args, **kwargs): # If it's being created and no expiration date has been set, set it to # 30 days into the future. if not self.pk and not self.expiration_date: self.expiration_date = date.today() + timedelta(days=30) super(Quote, self).save(*args, **kwargs) @property def total_price(self): return self.products.aggregate(Sum('price')).get('price__sum') def generate_contracts(self): """ Returns a list of (unsaved) contracts for the associated ProductQuotes, along with the products that must be linked to each. """ customer = self.opportunity.customer data = {} for product in self.products.all(): if not product.plan: continue key = (product.plan, product.start_date, product.end_date) if key not in data: # Create the contract and add the current product. # TODO: Generate contract number; using tracking_number now. contract_number = self.tracking_number + '-' + str(len(data)) contract = Contract( number=contract_number, service_sku=product.plan, start_date=product.start_date, end_date=product.end_date, customer=customer, ) data[key] = { 'contract': contract, 'products': [product.product], } else: # Add the current product only. data[key]['products'].append(product.product) return data.values()
class ModelWithUniqueSlugMonth(Model): date = DateField() slug = AutoSlugField(unique_with='date__month')
class Shared(Model): category = CharField(max_length=4, choices=CATEGORIES, default='FB') who_shared = ForeignKey(NgoUser) date_shared = DateField(null=False) visible_event = ForeignKey(Market)
def generate_federal_account_query(queryset, account_type, tas_id, filters): """ Group by federal account (and budget function/subfunction) and SUM all other fields """ derived_fields = { "reporting_agency_name": StringAgg("submission__reporting_agency_name", "; ", distinct=True), "budget_function": StringAgg(f"{tas_id}__budget_function_title", "; ", distinct=True), "budget_subfunction": StringAgg(f"{tas_id}__budget_subfunction_title", "; ", distinct=True), "submission_period": get_fyp_or_q_notation("submission"), "agency_identifier_name": get_agency_name_annotation(tas_id, "agency_id"), "last_modified_date" + NAMING_CONFLICT_DISCRIMINATOR: Cast(Max("submission__published_date"), output_field=DateField()), "gross_outlay_amount": Sum(generate_gross_outlay_amount_derived_field(filters, account_type)), "gross_outlay_amount_fyb_to_period_end": Sum(generate_gross_outlay_amount_derived_field(filters, account_type)), } if account_type != "account_balances": derived_fields.update( { "downward_adj_prior_yr_ppaid_undeliv_orders_oblig_refunds_cpe": Sum( generate_ussgl487200_derived_field(filters) ), "downward_adj_prior_yr_paid_delivered_orders_oblig_refunds_cpe": Sum( generate_ussgl497200_derived_field(filters) ), } ) if account_type == "award_financial": derived_fields = award_financial_derivations(derived_fields) queryset = queryset.annotate(**derived_fields) # List of all columns that may appear in A, B, or C files that can be summed all_summed_cols = [ "budget_authority_unobligated_balance_brought_forward", "adjustments_to_unobligated_balance_brought_forward", "budget_authority_appropriated_amount", "borrowing_authority_amount", "contract_authority_amount", "spending_authority_from_offsetting_collections_amount", "total_other_budgetary_resources_amount", "total_budgetary_resources", "obligations_incurred", "deobligations_or_recoveries_or_refunds_from_prior_year", "unobligated_balance", "status_of_budgetary_resources_total", "transaction_obligated_amount", ] # Group by all columns within the file that can't be summed fed_acct_values_dict = query_paths[account_type]["federal_account"] grouped_cols = [fed_acct_values_dict[val] for val in fed_acct_values_dict if val not in all_summed_cols] queryset = queryset.values(*grouped_cols) # Sum all fields from all_summed_cols that appear in this file values_dict = query_paths[account_type] summed_cols = { val: Sum(values_dict["treasury_account"].get(val, None)) for val in values_dict["federal_account"] if val in all_summed_cols } return queryset.annotate(**summed_cols)
class Comic(BaseModel): """Comic metadata.""" path = CharField(db_index=True, max_length=128) volume = ForeignKey(Volume, db_index=True, on_delete=CASCADE) series = ForeignKey(Series, db_index=True, on_delete=CASCADE) imprint = ForeignKey(Imprint, db_index=True, on_delete=CASCADE) publisher = ForeignKey(Publisher, db_index=True, on_delete=CASCADE) issue = DecimalField(db_index=True, decimal_places=2, max_digits=6, default=0.0) title = CharField(db_index=True, max_length=64, null=True) # Date year = PositiveSmallIntegerField(null=True) month = PositiveSmallIntegerField(null=True) day = PositiveSmallIntegerField(null=True) # Summary summary = TextField(null=True) notes = TextField(null=True) description = TextField(null=True) # Ratings critical_rating = CharField(db_index=True, max_length=32, null=True) maturity_rating = CharField(db_index=True, max_length=32, null=True) user_rating = CharField(db_index=True, max_length=32, null=True) # alpha2 fields for countries country = CharField(db_index=True, max_length=32, null=True) language = CharField(db_index=True, max_length=16, null=True) # misc page_count = PositiveSmallIntegerField(db_index=True, default=0) cover_image = CharField(max_length=64, null=True) read_ltr = BooleanField(default=True) web = URLField(null=True) format = CharField(max_length=16, null=True) scan_info = CharField(max_length=32, null=True) # ManyToMany credits = ManyToManyField(Credit) tags = ManyToManyField(Tag) teams = ManyToManyField(Team) characters = ManyToManyField(Character) locations = ManyToManyField(Location) series_groups = ManyToManyField(SeriesGroup) story_arcs = ManyToManyField(StoryArc) genres = ManyToManyField(Genre) # Ignore these, they seem useless: # # black_and_white = BooleanField(default=False) # price = DecimalField(decimal_places=2, max_digits=9, null=True) # rights = CharField(max_length=64, null=True) # manga = BooleanField(default=False) # last_mark = PositiveSmallIntegerField(null=True) # # These are potentially useful, but too much work right now: # # is_version_of = CharField(max_length=64, null=True) # alternate_issue = DecimalField(decimal_places=2, max_digits=6, null=True) # alternate_volumes = ManyToManyField(Volume, related_name="alternate_volume") # identifier = CharField(max_length=64, null=True) # codex only library = ForeignKey(Library, on_delete=CASCADE, db_index=True) sort_name = CharField(db_index=True, max_length=32) date = DateField(db_index=True, null=True) decade = PositiveSmallIntegerField(db_index=True, null=True) size = PositiveSmallIntegerField(db_index=True) max_page = PositiveSmallIntegerField(default=0) parent_folder = ForeignKey(Folder, db_index=True, on_delete=CASCADE, null=True, related_name="comic_in") folder = ManyToManyField(Folder) cover_path = CharField(max_length=32) myself = ForeignKey("self", on_delete=CASCADE, null=True, related_name="comic") class Meta: """Constraints.""" # prevents None path comics from being duplicated unique_together = ("path", "volume", "year", "issue") verbose_name = "Issue" def _set_date(self): """Compute a date for the comic.""" year = self.year if self.year is not None else datetime.MINYEAR month = self.month if self.month is not None else 1 day = self.day if self.day is not None else 1 self.date = datetime.date(year, month, day) def _set_decade(self): """Compute a decade for the comic.""" if self.year is None: self.decade = None else: self.decade = self.year - (self.year % 10) def _get_display_issue(self): """Get the issue number, even if its a half issue.""" if self.issue % 1 == 0: issue_str = f"#{int(self.issue):0>3d}" else: issue_str = f"#{self.issue:05.1f}" return issue_str def save(self, *args, **kwargs): """Save computed fields.""" self._set_date() self._set_decade() self.sort_name = f"{self.volume.sort_name} {self.issue:06.1f}" super().save(*args, **kwargs)
class FileModel(Model): id = BigAutoField(primary_key=True) fk_parent = ForeignKey( "self", on_delete=CASCADE, related_name="children", blank=True, null=True, ) fk_user = ForeignKey(User, on_delete=CASCADE, related_name="files") name = CharField(max_length=300) photo = ImageField(upload_to="files/", blank=True, null=True) is_public = BooleanField(default=False) issue_date = DateTimeField(auto_now_add=True) update_date = DateTimeField(auto_now=True) delete_date = DateField(blank=True, null=True) class Meta: ordering = ["id"] def __str__(self): if self.fk_parent: return f"{self.fk_parent.id} / {self.id} - {self.name}" return f"/ {self.id} - {self.name}" def parents_ids(self): """ For Validation Checks """ if self.fk_parent: all_parents_ids = self.fk_parent.parents_ids() if all_parents_ids: return [*all_parents_ids, self.fk_parent.id] return [self.fk_parent.id] def clean(self): if self.fk_parent: err = "File cannot be parent of himself." if self.pk == self.fk_parent.pk: raise ValidationError({'fk_parent': err}) if 9 < self.fk_parent.children.count(): raise ValidationError({ 'fk_parent': "Parent file reached maximum allowed files." }) parents_ids = self.parents_ids() if parents_ids: if self.pk in parents_ids: raise ValidationError({'fk_parent': err}) def parents_as_list(self, i=1): if self.fk_parent and i < 5: all_parents = self.fk_parent.parents_as_list(i + 1) parent = { "order": i, "id": self.fk_parent.id, "name": self.fk_parent.name } if all_parents: return [*all_parents, parent] return [parent] def user_as_dict(self): full_name = self.fk_user.first_name + " " + self.fk_user.last_name return { "id": self.fk_user.pk, "username": self.fk_user.username, "name": full_name.strip(), "email": self.fk_user.email } def children_as_list(self): data = [] for child in self.children.all(): child_photo = child.photo or {"url": "http://localhost:8000/"} data.append({ "id": child.pk, "name": child.name, "photo": child_photo.get("url"), "is_public": child.is_public }) return data
class AbstractAct(CremeEntity): name = CharField(_('Name of the commercial action'), max_length=100) expected_sales = PositiveIntegerField(_('Expected sales')) cost = PositiveIntegerField(_('Cost of the commercial action'), blank=True, null=True) goal = TextField(_('Goal of the action'), blank=True) start = DateField(_('Start')) due_date = DateField(_('Due date')) act_type = ForeignKey(ActType, verbose_name=_('Type'), on_delete=PROTECT) segment = ForeignKey(MarketSegment, verbose_name=_('Related segment'), on_delete=PROTECT) creation_label = _('Create a commercial action') save_label = _('Save the commercial action') _related_opportunities = None class Meta: abstract = True manager_inheritance_from_future = True app_label = 'commercial' verbose_name = _('Commercial action') verbose_name_plural = _('Commercial actions') ordering = ('name', ) def __str__(self): return self.name def clean(self): super().clean() start = self.start due_date = self.due_date if not due_date or not start or due_date < start: raise ValidationError( gettext("Due date can't be before start."), code='duedate_before_start', ) def get_absolute_url(self): return reverse('commercial__view_act', args=(self.id, )) @staticmethod def get_create_absolute_url(): return reverse('commercial__create_act') def get_edit_absolute_url(self): return reverse('commercial__edit_act', args=(self.id, )) @staticmethod def get_lv_absolute_url(): return reverse('commercial__list_acts') def get_made_sales(self): return sum(o.made_sales for o in self.get_related_opportunities() if o.made_sales) def get_estimated_sales(self): return sum(o.estimated_sales for o in self.get_related_opportunities() if o.estimated_sales) def get_related_opportunities(self): relopps = self._related_opportunities if relopps is None: relopps = [ *get_opportunity_model().objects.filter( is_deleted=False, relations__type=REL_SUB_COMPLETE_GOAL, relations__object_entity=self.id, ) ] self._related_opportunities = relopps return relopps def _post_save_clone(self, source): ActObjective.objects.bulk_create([ ActObjective( name=objective.name, act=self, counter=objective.counter, counter_goal=objective.counter_goal, ctype=objective.ctype, ) for objective in ActObjective.objects.filter( act=source).order_by('id') ])
class Video(BasePage): resource_type = "video" parent_page_types = ["Videos"] subpage_types = [] template = "video.html" # Content fields description = RichTextField( blank=True, default="", features=RICH_TEXT_FEATURES_SIMPLE, help_text="Optional short text description, max. 400 characters", max_length=400, ) body = RichTextField( blank=True, default="", features=RICH_TEXT_FEATURES, help_text=( "Optional body content. Supports rich text, images, embed via URL, " "embed via HTML, and inline code snippets"), ) related_links_mdn = StreamField( StreamBlock([("link", ExternalLinkBlock())], required=False), null=True, blank=True, help_text="Optional links to MDN Web Docs for further reading", verbose_name="Related MDN links", ) image = ForeignKey( "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, related_name="+", ) types = CharField(max_length=14, choices=VIDEO_TYPE, default="conference") duration = CharField( max_length=30, blank=True, null=True, help_text= ("Optional video duration in MM:SS format e.g. “12:34”. Shown when the " "video is displayed as a card"), ) transcript = RichTextField( blank=True, default="", features=RICH_TEXT_FEATURES, help_text="Optional text transcript of the video, supports rich text", ) video_url = StreamField( StreamBlock([("embed", EmbedBlock())], min_num=1, max_num=1, required=True), help_text= ("Embed URL for the video e.g. https://www.youtube.com/watch?v=kmk43_2dtn0" ), ) speakers = StreamField( StreamBlock( [("speaker", PageChooserBlock(target_model="people.Person"))], required=False, ), blank=True, null=True, help_text= "Optional list of people associated with or starring in the video", ) # Card fields card_title = CharField("Title", max_length=140, blank=True, default="") card_description = TextField("Description", max_length=400, blank=True, default="") card_image = ForeignKey( "mozimages.MozImage", null=True, blank=True, on_delete=SET_NULL, related_name="+", verbose_name="Image", ) # Meta fields date = DateField("Upload date", default=datetime.date.today) keywords = ClusterTaggableManager(through=VideoTag, blank=True) # Content panels content_panels = BasePage.content_panels + [ FieldPanel("description"), ImageChooserPanel("image"), StreamFieldPanel("video_url"), FieldPanel("body"), StreamFieldPanel("related_links_mdn"), FieldPanel("transcript"), ] # Card panels card_panels = [ FieldPanel("card_title"), FieldPanel("card_description"), ImageChooserPanel("card_image"), ] # Meta panels meta_panels = [ FieldPanel("date"), StreamFieldPanel("speakers"), MultiFieldPanel( [InlinePanel("topics")], heading="Topics", help_text= ("These are the topic pages the video will appear on. The first topic " "in the list will be treated as the primary topic and will be shown " "in the page’s related content."), ), FieldPanel("duration"), MultiFieldPanel( [FieldPanel("types")], heading="Type", help_text="Choose a video type to help people search for the video", ), MultiFieldPanel( [ FieldPanel("seo_title"), FieldPanel("search_description"), ImageChooserPanel("social_image"), FieldPanel("keywords"), ], heading="SEO", help_text=( "Optional fields to override the default title and description " "for SEO purposes"), ), ] settings_panels = [FieldPanel("slug")] # Tabs edit_handler = TabbedInterface([ ObjectList(content_panels, heading="Content"), ObjectList(card_panels, heading="Card"), ObjectList(meta_panels, heading="Meta"), ObjectList(settings_panels, heading="Settings", classname="settings"), ]) @property def primary_topic(self): """Return the first (primary) topic specified for the video.""" video_topic = self.topics.first() return video_topic.topic if video_topic else None @property def read_time(self): return str(readtime.of_html(str(self.body))) @property def related_resources(self): """Returns resources that are related to the current resource, i.e. live, public articles and videos which have the same topics.""" topic_pks = [topic.topic.pk for topic in self.topics.all()] return get_combined_articles_and_videos( self, topics__topic__pk__in=topic_pks) def has_speaker(self, person): for speaker in self.speakers: # pylint: disable=not-an-iterable if str(speaker.value) == str(person.title): return True return False
class Kid(Model): class Color(IntegerChoices): BLACK = 1, _("Preto") BROWN = 2, _("Castanhos") BLONDE = 3, _("Loiro") RED = 4, _("Ruivo") BLUE = ( 5, _("Azul"), ) SWARTHY = 6, _("Morena") WHITE = 7, _("Branca") # required fiels name = CharField("Nome", max_length=255, db_index=True, unique=True) url = URLField("URL") full_text = TextField() # optional indexed fields dob = DateField("Data de nascimento", null=True, blank=True, db_index=True) missing_since = DateField("Desaparecida(o) desde", null=True, blank=True, db_index=True) eyes = CharField( "Cor dos olhos", max_length=50, choices=Color.choices, null=True, blank=True, db_index=True, ) hair = CharField( "Cor dos cabelos", max_length=50, choices=Color.choices, null=True, blank=True, db_index=True, ) skin = CharField( "Cor da pele", max_length=50, choices=Color.choices, null=True, blank=True, db_index=True, ) # optional fields mother = CharField("Mãe", max_length=255, null=True, blank=True) father = CharField("Pai", max_length=255, null=True, blank=True) last_seen_at_city = CharField( "Cidade onde foi vista(o) pela última vez", max_length=255, null=True, blank=True, db_index=True, ) last_seen_at_state = CharField( "UF onde foi vista(o) pela última vez", max_length=2, null=True, blank=True, db_index=True, ) age_at_occurrence = IntegerField("Idade quando desapareceu", null=True, blank=True) class Meta: verbose_name = "criança" ordering = ("name", ) def __str__(self): return self.name
class Walker(Model): class Meta: verbose_name = 'Волкер' verbose_name_plural = 'Волкеры' user = OneToOneField(User, on_delete=CASCADE, verbose_name='Пользователь') photo = ImageField(verbose_name='Аватар', upload_to=user_directory_path) specialization = CharField(max_length=50, verbose_name='Специализация') extra_photo_1 = ImageField(verbose_name='Дополнительное фото 1 на странице специалистов', blank=True, null=True, upload_to=user_directory_path) extra_photo_2 = ImageField(verbose_name='Дополнительное фото 2 на странице специалистов', blank=True, null=True, upload_to=user_directory_path) extra_photo_3 = ImageField(verbose_name='Дополнительное фото 3 на странице специалистов', blank=True, null=True, upload_to=user_directory_path) short_card_photo_1 = ImageField(verbose_name='1 фото на странице выгула', upload_to=user_directory_path) short_card_photo_2 = ImageField(verbose_name='2 фото на странице выгула', upload_to=user_directory_path) history = TextField(verbose_name='Текст на странице специалистов', blank=True, null=True) phrase = CharField(max_length=100, verbose_name="Фраза на странице выгула", blank=True) walking_map = ImageField(verbose_name='Карта выгула', upload_to=user_directory_path, blank=True) birth_date = DateField(verbose_name='Дата рождения') green_zones = ManyToManyField(WalkingZone, related_name='green_zones', verbose_name='Зеленые зоны') blue_zones = ManyToManyField(WalkingZone, related_name='blue_zones', verbose_name='Голубые зоны') can_change_dates = BooleanField(default=True, verbose_name='Может изменить даты выгула') phone_regex = RegexValidator(regex=r'^\+7\d{10}$', message="Телефонный номер должен быть в формате: '+79999999999'") phone = CharField(validators=[phone_regex], max_length=12, blank=True, verbose_name='Телефон') def __str__(self): return self.user.get_full_name() @staticmethod def _get_structured_walking_dates(month_days_amount, walking_dates): month = [(idx + 1, [{'is_free': True} for _ in range(16)]) for idx in range(month_days_amount)] for walking_date in walking_dates: if walking_date.dog_owner_name: month[walking_date.day][1][walking_date.hour - 7] = {'is_free': False, 'address': walking_date.address, 'dog_owner_name': walking_date.dog_owner_name, 'breed': walking_date.breed, 'type': walking_date.get_type_display()} else: month[walking_date.day][1][walking_date.hour - 7] = {'is_free': False} return month def get_walking_dates(self): cur_month_days_amount = get_cur_month_days_amount() next_month_days_amount = get_cur_month_days_amount(is_next_month=True) walking_dates = list(self.walkingdate_set.get_queryset()) cur_month_walking_dates = [date for date in walking_dates if not date.month] next_month_walking_dates = [date for date in walking_dates if date.month] cur_month = self._get_structured_walking_dates(cur_month_days_amount, cur_month_walking_dates) next_month = self._get_structured_walking_dates(next_month_days_amount, next_month_walking_dates) cur_month = cut_into_weeks(cur_month) next_month = cut_into_weeks(next_month) return cur_month, next_month def _get_walking_dates_list(self): return list(WalkingDate.objects.filter(walker_id=self.id).values('day', 'hour', 'month', 'dog_owner_name', 'address', 'breed', 'type')) def _fill_walking_dates_from_form_data(self, form_data): cur_month_days_amount = get_cur_month_days_amount() for walking_date in form_data: day, hours = walking_date.split('-') day = int(day) month = day > cur_month_days_amount - 1 if month: day -= cur_month_days_amount for hour in hours.split(','): WalkingDate.objects.create(day=day, hour=hour, walker_id=self.id, month=month) def set_walking_dates(self, data): prev_walking_dates_version = self._get_walking_dates_list() WalkingDate.objects.filter(walker_id=self.id).exclude(~Q(dog_owner_name='')).exclude(~Q(address='')).delete() if data: data = data.split(';') self._fill_walking_dates_from_form_data(data) cur_walking_dates_version = self._get_walking_dates_list() if prev_walking_dates_version != cur_walking_dates_version: Walker.objects.filter(id=self.id).update(can_change_dates=False)
class ModelWithAcceptableEmptyDependency(Model): date = DateField(blank=True, null=True) slug = AutoSlugField(unique_with='date')
def test_DateField(self): lazy_func = lazy(lambda: datetime.date.today(), datetime.date) self.assertIsInstance(DateField().get_prep_value(lazy_func()), datetime.date)
class ModelWithUniqueSlugDate(Model): date = DateField() slug = AutoSlugField(unique_with='date')
class ModelWithWrongFieldOrder(Model): slug = AutoSlugField(unique_with='date') date = DateField(blank=False, null=False)
def get_months_plot(queryset, field) -> list: # DateField or DateTimeField return queryset.annotate(date=Cast('datetime', output_field=DateField()))\ .values('date').annotate(field=TruncMonth('date'))\ .values('field').annotate(c=Count(field)).values('field', 'c')\ .order_by('field')