Created
June 22, 2020 16:15
-
-
Save oma256/bfd945c7d6f6e89ab64830aec26ded0e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@admin.register(PatientIndicator) | |
class PatientIndicator(ExportMixin, admin.ModelAdmin): | |
list_display = ( | |
'get_patient', | |
'dyspnea', | |
'position_bed', | |
'heartbeat', | |
'stack', | |
'weight', | |
'arterial_pressure', | |
'pulse', | |
'deviation', | |
'create_at', | |
) | |
fieldsets = ( | |
( | |
None, | |
{ | |
'fields': ( | |
'patient', | |
'dyspnea', | |
'position_bed', | |
'heartbeat', | |
'stack', | |
'weight', | |
'arterial_pressure', | |
'pulse', | |
'create_at', | |
), | |
} | |
), | |
) | |
list_filter = ( | |
('create_at', DateFieldListFilter), | |
) | |
search_fields = ( | |
'patient__user__first_name', | |
'patient__user__last_name', | |
'patient__user__middle_name', | |
) | |
list_select_related = ('patient',) | |
resource_class = PatientIndicatorResources | |
readonly_fields = ('create_at',) | |
def get_patient(self, obj): | |
return obj.patient.__str__() | |
get_patient.short_description = 'пациент' | |
def get_export_formats(self): | |
""" | |
Return available export formats | |
""" | |
return [base_formats.XLSX] | |
def get_queryset(self, request): | |
qs = self.model._default_manager.get_queryset() | |
if request.user.is_superuser: | |
return qs | |
return qs.filter( | |
patient__doctor=request.user.doctor | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PatientIndicatorFilter(django_filters.FilterSet): | |
filter = django_filters.CharFilter(field_name='create_at', method='week_month_filter') | |
class Meta: | |
model = PatientIndicator | |
fields = ['filter'] | |
def week_month_filter(self, queryset, name, value): | |
today = date.today() | |
if value == 'week': | |
start_week = today - datetime.timedelta(today.weekday()) | |
end_week = start_week + datetime.timedelta(7) | |
return queryset.filter(create_at__range=[start_week, end_week]) | |
elif value == 'month': | |
return queryset.filter(create_at__month=today.month) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PatientIndicator(models.Model): | |
patient = models.ForeignKey( | |
Patient, | |
verbose_name='пациент', | |
related_name='indicator', | |
on_delete=models.CASCADE, | |
null=True, | |
) | |
dyspnea = models.PositiveSmallIntegerField( | |
verbose_name='одышка', | |
choices=DYSPNEA_CHOICE | |
) | |
position_bed = models.PositiveSmallIntegerField( | |
verbose_name='положение в постели', | |
choices=POSITION_BED_CHOICES | |
) | |
heartbeat = models.PositiveSmallIntegerField( | |
verbose_name='сердцебиение', | |
choices=HEARTBEAT_CHOICES | |
) | |
stack = models.PositiveSmallIntegerField( | |
verbose_name='отеки', | |
choices=STACK_CHOICES | |
) | |
weight = models.PositiveSmallIntegerField(verbose_name='вес') | |
arterial_pressure = models.CharField(verbose_name='АД', max_length=12) | |
pulse = models.PositiveSmallIntegerField(verbose_name='пульс') | |
deviation = models.PositiveIntegerField(verbose_name='отклонение', null=True) | |
create_at = models.DateTimeField( | |
verbose_name='дата создания', | |
auto_now=True, | |
) | |
class Meta: | |
verbose_name = 'индикатор пациента' | |
verbose_name_plural = 'индикаторы пациентов' | |
def __str__(self): | |
return f'Индикатор {self.patient.__str__()}' | |
@property | |
def deviation_count(self): | |
count = 0 | |
if self.dyspnea_check['deviation']: | |
count += 1 | |
if self.position_bed_check['deviation']: | |
count += 1 | |
if self.heartbeat_check['deviation']: | |
count += 1 | |
if self.stack_check['deviation']: | |
count += 1 | |
if self.weight_check['deviation']: | |
count += 1 | |
if self.arterial_pressure_check['deviation']: | |
count += 1 | |
if self.pulse_check['deviation']: | |
count += 1 | |
return count | |
@property | |
def dyspnea_check(self): | |
deviation = self.dyspnea == 3 | |
data = dict( | |
deviation=deviation, | |
value=self.get_dyspnea_display(), | |
description=self.get_dyspnea_display() | |
) | |
return data | |
@property | |
def position_bed_check(self): | |
deviation = self.position_bed == 3 | |
data = dict( | |
deviation=deviation, | |
value=self.get_position_bed_display(), | |
description=self.get_position_bed_display() | |
) | |
return data | |
@property | |
def heartbeat_check(self): | |
deviation = self.heartbeat == 3 | |
data = dict( | |
deviation=deviation, | |
value=self.get_heartbeat_display(), | |
description=self.get_heartbeat_display() | |
) | |
return data | |
@property | |
def stack_check(self): | |
deviation = self.stack == 4 or self.stack == 3 | |
data = dict( | |
deviation=deviation, | |
value=self.get_stack_display(), | |
description=self.get_stack_display() | |
) | |
return data | |
@property | |
def weight_check(self): | |
deviation = False | |
if self.weight > self.patient.weight: | |
deviation = True | |
description = _('У вас избыточный вес на %s кг') % (self.weight - self.patient.weight) \ | |
if deviation else '' | |
data = dict( | |
deviation=deviation, | |
value=self.weight, | |
description=description | |
) | |
return data | |
@property | |
def arterial_pressure_check(self): | |
try: | |
ar_top = int(self.arterial_pressure.split('/')[0]) | |
ar_bottom = int(self.arterial_pressure.split('/')[1]) | |
deviation = False | |
if ar_top > 140: | |
deviation = True | |
if ar_bottom < 80: | |
deviation = True | |
except: | |
deviation = None | |
data = dict( | |
deviation=deviation, | |
value=self.arterial_pressure, | |
description=self.arterial_pressure | |
) | |
return data | |
@property | |
def pulse_check(self): | |
deviation = False | |
if self.pulse > 90: | |
deviation = True | |
if self.pulse < 60: | |
deviation = True | |
data = dict( | |
deviation=deviation, | |
value=self.pulse, | |
description=self.pulse | |
) | |
return data | |
@receiver(post_save, sender=PatientIndicator) | |
def post_save_notice(sender, instance, created, **kwargs): | |
if created: | |
instance.deviation = instance.deviation_count | |
instance.save() | |
if created and instance.deviation_count: | |
Notification.objects.create( | |
user=instance.patient.user, | |
notification_type=DEVIATION, | |
deviation_count=instance.deviation_count | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PatientIndicatorSerializer(serializers.ModelSerializer): | |
class Meta: | |
model = PatientIndicator | |
fields = [ | |
'id', | |
'patient', | |
'dyspnea', | |
'position_bed', | |
'heartbeat', | |
'stack', | |
'weight', | |
'arterial_pressure', | |
'pulse', | |
'create_at', | |
'deviation_count' | |
] | |
extra_kwargs = { | |
'patient': { | |
'read_only': True | |
}, | |
'create_at': { | |
'read_only': True | |
}, | |
'deviation_count': { | |
'read_only': True | |
} | |
} | |
def create(self, validated_data): | |
patient = self.context['request'].user.patient | |
if patient.indicator.filter(create_at__contains=timezone.now().date()).exists(): | |
raise serializers.ValidationError({"message": "Вы уже заполнили анкету на сегодня."}) | |
return super().create(validated_data) | |
def save(self, **kwargs): | |
self.validated_data['patient'] = self.context['request'].user.patient | |
return super().save(**kwargs) | |
class PatientIndicatorDetailSerializer(serializers.ModelSerializer): | |
dyspnea = serializers.DictField(source='dyspnea_check') | |
position_bed = serializers.DictField(source='position_bed_check') | |
heartbeat = serializers.DictField(source='heartbeat_check') | |
stack = serializers.DictField(source='stack_check') | |
weight = serializers.DictField(source='weight_check') | |
arterial_pressure = serializers.DictField(source='arterial_pressure_check') | |
pulse = serializers.DictField(source='pulse_check') | |
class Meta: | |
model = PatientIndicator | |
fields = [ | |
'id', | |
'patient', | |
'create_at', | |
'dyspnea', | |
'position_bed', | |
'heartbeat', | |
'stack', | |
'weight', | |
'arterial_pressure', | |
'pulse', | |
'deviation_count' | |
] | |
class DoctorPatientIndicatorHistory(serializers.ModelSerializer): | |
class Meta: | |
model = PatientIndicator | |
fields = [ | |
'id', | |
'patient', | |
'dyspnea', | |
'position_bed', | |
'heartbeat', | |
'stack', | |
'weight', | |
'arterial_pressure', | |
'pulse', | |
'create_at', | |
'deviation_count' | |
] | |
extra_kwargs = { | |
'patient': { | |
'read_only': True | |
}, | |
'create_at': { | |
'read_only': True | |
}, | |
'deviation_count': { | |
'read_only': True | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PatientIndicatorListDetailCreateView(ListCreateAPIView): | |
permission_classes = (IsAuthenticated, IsPatient) | |
serializer_class = PatientIndicatorSerializer | |
filter_backends = [DjangoFilterBackend] | |
filterset_class = PatientIndicatorFilter | |
queryset = PatientIndicator.objects.all() | |
lookup_url_kwarg = 'patient_id' | |
def get_queryset(self): | |
patient_id = self.kwargs.get(self.lookup_url_kwarg) | |
if patient_id: | |
return self.queryset.filter( | |
patient__user=patient_id | |
).order_by('-create_at')[:10] | |
return self.queryset.filter(patient=self.request.user.patient) | |
class PatientIndicatorDetail(RetrieveAPIView): | |
permission_classes = (IsAuthenticated,) | |
serializer_class = PatientIndicatorDetailSerializer | |
queryset = PatientIndicator.objects.all() | |
def get_queryset(self): | |
patient_id = self.kwargs.get('patient_id', None) | |
if patient_id: | |
return self.queryset.filter(patient=patient_id) | |
return self.queryset.filter(patient=self.request.user.patient) | |
def get_object(self): | |
indicator_id = self.kwargs.get('indicator_id', None) | |
if indicator_id: | |
indicator = self.queryset.filter(pk=indicator_id).first() | |
if indicator: | |
return indicator | |
raise Http404 | |
return super().get_object() | |
class IndicatorToday(APIView): | |
permission_classes = (IsAuthenticated,) | |
def get(self, request, *args, **kwargs): | |
indicator = PatientIndicator.objects.filter( | |
create_at__contains=timezone.now().date(), | |
patient=request.user.patient, | |
).first() | |
return Response( | |
{ | |
"id": getattr(indicator, 'id', None), | |
"isTodaySend": indicator is not None | |
} | |
) | |
class DoctorPatientIndicatorListAPI(ListAPIView): | |
permission_classes = (IsAuthenticated, IsDoctor) | |
serializer_class = DoctorPatientIndicatorHistory | |
queryset = PatientIndicator.objects.all() | |
lookup_url_kwarg = 'patient_id' | |
def get_queryset(self): | |
patient_id = self.kwargs.get(self.lookup_url_kwarg) | |
if patient_id: | |
return self.queryset.filter( | |
patient__user=patient_id | |
).order_by('-create_at')[:10] | |
return self.queryset.filter(patient=self.request.user.patient) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment