bugungi kun
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
from .region import *
|
||||
from .district import *
|
||||
from .place import *
|
||||
from .place import *
|
||||
from .pharmacy import *
|
||||
from .doctor import *
|
||||
from .plan import *
|
||||
@@ -6,7 +6,7 @@ from core.apps.shared.models import District
|
||||
|
||||
@admin.register(District)
|
||||
class DistrictAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'user', 'created_at']
|
||||
list_display = ['id','name', 'user', 'created_at']
|
||||
search_fields = ['name']
|
||||
|
||||
|
||||
11
core/apps/shared/admin/doctor.py
Normal file
11
core/apps/shared/admin/doctor.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import Doctor
|
||||
|
||||
|
||||
@admin.register(Doctor)
|
||||
class DoctorAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'first_name', 'last_name', 'phone_number']
|
||||
search_fields = list_display
|
||||
|
||||
10
core/apps/shared/admin/pharmacy.py
Normal file
10
core/apps/shared/admin/pharmacy.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import Pharmacy
|
||||
|
||||
|
||||
@admin.register(Pharmacy)
|
||||
class PharmacyAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'name', 'inn', 'owner_phone', 'responsible_phone']
|
||||
search_fields = list_display
|
||||
@@ -6,5 +6,5 @@ from core.apps.shared.models import Place
|
||||
|
||||
@admin.register(Place)
|
||||
class PlaceAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'user', 'district']
|
||||
list_display = ['id', 'name', 'user', 'district']
|
||||
search_fields = ['name']
|
||||
10
core/apps/shared/admin/plan.py
Normal file
10
core/apps/shared/admin/plan.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import Plan
|
||||
|
||||
|
||||
@admin.register(Plan)
|
||||
class PlanAdmin(admin.ModelAdmin):
|
||||
list_display = ['id', 'title', 'date']
|
||||
search_fields = list_display
|
||||
@@ -6,5 +6,5 @@ from core.apps.shared.models import Region
|
||||
|
||||
@admin.register(Region)
|
||||
class RegionAdmin(admin.ModelAdmin):
|
||||
list_display = ['name', 'users_count']
|
||||
list_display = ['id', 'name', 'users_count']
|
||||
search_fields = ['name']
|
||||
75
core/apps/shared/migrations/0005_doctor_pharmacy_plan.py
Normal file
75
core/apps/shared/migrations/0005_doctor_pharmacy_plan.py
Normal file
@@ -0,0 +1,75 @@
|
||||
# Generated by Django 5.2 on 2025-11-22 12:27
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('shared', '0004_place'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Doctor',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('first_name', models.CharField(max_length=200)),
|
||||
('last_name', models.CharField(max_length=200)),
|
||||
('phone_number', models.CharField(max_length=15)),
|
||||
('work_place', models.CharField(max_length=200)),
|
||||
('sphere', models.CharField(max_length=200)),
|
||||
('description', models.TextField()),
|
||||
('longitude', models.FloatField(default=0.0)),
|
||||
('latitude', models.FloatField(default=0.0)),
|
||||
('extra_location', models.JSONField()),
|
||||
('district', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doctors', to='shared.district')),
|
||||
('place', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doctors', to='shared.place')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='doctors', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Pharmacy',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('inn', models.CharField(max_length=200)),
|
||||
('owner_phone', models.CharField(max_length=15)),
|
||||
('responsible_phone', models.CharField(max_length=15)),
|
||||
('longitude', models.FloatField(default=0.0)),
|
||||
('latitude', models.FloatField(default=0.0)),
|
||||
('extra_location', models.JSONField()),
|
||||
('district', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pharmacies', to='shared.district')),
|
||||
('place', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pharmacies', to='shared.place')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pharmacies', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Plan',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('title', models.CharField(max_length=200)),
|
||||
('description', models.TextField()),
|
||||
('date', models.DateField()),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='plans', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,4 +1,7 @@
|
||||
from .base import *
|
||||
from .region import *
|
||||
from .district import *
|
||||
from .place import *
|
||||
from .place import *
|
||||
from .doctor import *
|
||||
from .pharmacy import *
|
||||
from .plan import *
|
||||
29
core/apps/shared/models/doctor.py
Normal file
29
core/apps/shared/models/doctor.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from django.db import models
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import BaseModel, District, Place
|
||||
# accounts
|
||||
from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class Doctor(BaseModel):
|
||||
# information
|
||||
first_name = models.CharField(max_length=200)
|
||||
last_name = models.CharField(max_length=200)
|
||||
phone_number = models.CharField(max_length=15)
|
||||
work_place = models.CharField(max_length=200)
|
||||
sphere = models.CharField(max_length=200)
|
||||
description = models.TextField()
|
||||
# relations
|
||||
district = models.ForeignKey(District, on_delete=models.CASCADE, related_name='doctors')
|
||||
place = models.ForeignKey(Place, on_delete=models.CASCADE, related_name='doctors')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='doctors')
|
||||
# location
|
||||
longitude = models.FloatField(default=0.00)
|
||||
latitude = models.FloatField(default=0.00)
|
||||
extra_location = models.JSONField()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name} - {self.work_place}"
|
||||
|
||||
|
||||
26
core/apps/shared/models/pharmacy.py
Normal file
26
core/apps/shared/models/pharmacy.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from django.db import models
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import BaseModel, District, Place
|
||||
# accounts
|
||||
from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class Pharmacy(BaseModel):
|
||||
# informations
|
||||
name = models.CharField(max_length=200)
|
||||
inn = models.CharField(max_length=200)
|
||||
owner_phone = models.CharField(max_length=15)
|
||||
responsible_phone = models.CharField(max_length=15)
|
||||
# relations
|
||||
district = models.ForeignKey(District, on_delete=models.CASCADE, related_name='pharmacies')
|
||||
place = models.ForeignKey(Place, on_delete=models.CASCADE, related_name='pharmacies')
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='pharmacies')
|
||||
# location
|
||||
longitude = models.FloatField(default=0.00)
|
||||
latitude = models.FloatField(default=0.00)
|
||||
extra_location = models.JSONField()
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.name} - {self.inn}"
|
||||
|
||||
17
core/apps/shared/models/plan.py
Normal file
17
core/apps/shared/models/plan.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from django.db import models
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import BaseModel
|
||||
# accounts
|
||||
from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class Plan(BaseModel):
|
||||
title = models.CharField(max_length=200)
|
||||
description = models.TextField()
|
||||
date = models.DateField()
|
||||
# relations
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='plans')
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
98
core/apps/shared/serializers/doctor.py
Normal file
98
core/apps/shared/serializers/doctor.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# django
|
||||
from django.db import transaction
|
||||
|
||||
# rest framework
|
||||
from rest_framework import serializers
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import Doctor, District, Place
|
||||
# accounts
|
||||
from core.apps.accounts.models import User
|
||||
|
||||
|
||||
class DoctorListSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Doctor
|
||||
fields = [
|
||||
'id',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'phone_number',
|
||||
'work_place',
|
||||
'description',
|
||||
'district',
|
||||
'place',
|
||||
'longitude',
|
||||
'latitude',
|
||||
'extra_location',
|
||||
'created_at',
|
||||
]
|
||||
|
||||
def get_district(self, obj):
|
||||
return {
|
||||
'id': obj.district.id,
|
||||
'name': obj.district.name,
|
||||
}
|
||||
|
||||
def get_place(self, obj):
|
||||
return {
|
||||
'id': obj.place.id,
|
||||
'name': obj.place.name,
|
||||
}
|
||||
|
||||
|
||||
class DoctorCreateUpdateSerializer(serializers.Serializer):
|
||||
first_name = serializers.CharField(required=False)
|
||||
last_name = serializers.CharField(required=False)
|
||||
phone_number = serializers.CharField(required=False)
|
||||
work_place = serializers.CharField(required=False)
|
||||
description = serializers.CharField(required=False)
|
||||
district = serializers.IntegerField(required=False)
|
||||
place = serializers.IntegerField(required=False)
|
||||
longitude = serializers.FloatField(required=False)
|
||||
latitude = serializers.FloatField(required=False)
|
||||
extra_location = serializers.JSONField(required=False)
|
||||
|
||||
def validate(self, data):
|
||||
if data.get('district'):
|
||||
district = District.objects.filter(id=data['district']).first()
|
||||
if not district:
|
||||
raise serializers.ValidationError({"district": "District topilamadi"})
|
||||
data['district_obj'] = district
|
||||
if data.get('place'):
|
||||
place = Place.objects.filter(id=data['place']).first()
|
||||
if not place:
|
||||
raise serializers.ValidationError({"place": "Place topilamadi"})
|
||||
data['place_obj'] = place
|
||||
return data
|
||||
|
||||
def create(self, validated_data):
|
||||
with transaction.atomic():
|
||||
return Doctor.objects.create(
|
||||
first_name=validated_data.get('first_name'),
|
||||
last_name=validated_data.get('last_name'),
|
||||
phone_number=validated_data.get('phone_number'),
|
||||
work_place=validated_data.get('work_place'),
|
||||
description=validated_data.get('description'),
|
||||
district=validated_data.get('district_obj'),
|
||||
place=validated_data.get('place_obj'),
|
||||
longitude=validated_data.get('longitude'),
|
||||
latitude=validated_data.get('latitude'),
|
||||
extra_location=validated_data.get('extra_location'),
|
||||
user=self.context.get('user'),
|
||||
)
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
with transaction.atomic():
|
||||
instance.first_name = validated_data.get('first_name', instance.first_name)
|
||||
instance.last_name = validated_data.get('last_name', instance.last_name)
|
||||
instance.phone_number = validated_data.get('phone_number', instance.phone_number)
|
||||
instance.work_place = validated_data.get('work_place', instance.work_place)
|
||||
instance.description = validated_data.get('description', instance.description)
|
||||
instance.district = validated_data.get('district_obj', instance.district)
|
||||
instance.place = validated_data.get('place_obj', instance.place)
|
||||
instance.longitude = validated_data.get('longitude', instance.longitude)
|
||||
instance.latitude = validated_data.get('latitude', instance.latitude)
|
||||
instance.extra_location = validated_data.get('extra_location', instance.extra_location)
|
||||
instance.save()
|
||||
return instance
|
||||
@@ -6,6 +6,8 @@ from core.apps.shared.views import region as region_view
|
||||
from core.apps.shared.views import district as dis_view
|
||||
# shared place view
|
||||
from core.apps.shared.views import place as pl_view
|
||||
# shared doctor view
|
||||
from core.apps.shared.views import doctor as dc_view
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
@@ -31,4 +33,12 @@ urlpatterns = [
|
||||
path('<int:id>/', pl_view.PlaceDeleteUpdateApiView.as_view(), name='place-update-delete-api'),
|
||||
]
|
||||
)),
|
||||
# doctor
|
||||
path('doctor/', include(
|
||||
[
|
||||
path('list/', dc_view.DoctorListApiView.as_view(), name='doctor-list-api'),
|
||||
path('create/', dc_view.DoctorCreateApiView.as_view(), name='doctor-create-api'),
|
||||
path('<int:id>/', dc_view.DoctorDeleteUpdateApiView.as_view(), name='doctor-update-delete-api'),
|
||||
]
|
||||
)),
|
||||
]
|
||||
@@ -55,7 +55,7 @@ class DistrictCreateApiView(generics.CreateAPIView, ResponseMixin):
|
||||
name = serializer.validated_data.get('name')
|
||||
obj = District.objects.create(name=name, user=request.user)
|
||||
return self.success_response(
|
||||
data=district_serializers.DistrictSerializer(obj),
|
||||
data=district_serializers.DistrictSerializer(obj).data,
|
||||
message='malumot qoshildi',
|
||||
status_code=201
|
||||
)
|
||||
|
||||
112
core/apps/shared/views/doctor.py
Normal file
112
core/apps/shared/views/doctor.py
Normal file
@@ -0,0 +1,112 @@
|
||||
# django
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
# rest framework
|
||||
from rest_framework import generics, permissions
|
||||
|
||||
# drf yasg
|
||||
from drf_yasg.utils import swagger_auto_schema
|
||||
|
||||
# shared
|
||||
from core.apps.shared.models import Doctor
|
||||
from core.apps.shared.serializers.doctor import DoctorCreateUpdateSerializer, DoctorListSerializer
|
||||
from core.apps.shared.serializers.base import SuccessResponseSerializer, BaseResponseSerializer
|
||||
from core.apps.shared.utils.response_mixin import ResponseMixin
|
||||
|
||||
|
||||
|
||||
class DoctorListApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = DoctorListSerializer
|
||||
queryset = Doctor.objects.all()
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
@swagger_auto_schema(
|
||||
responses={
|
||||
200: SuccessResponseSerializer(),
|
||||
400: BaseResponseSerializer(),
|
||||
500: BaseResponseSerializer(),
|
||||
}
|
||||
)
|
||||
def get(self, request):
|
||||
try:
|
||||
query = self.queryset.filter(user=request.user)
|
||||
serializer = self.serializer_class(query, many=True)
|
||||
return self.success_response(data=serializer.data, message='malumotlar fetch qilindi')
|
||||
except Exception as e:
|
||||
return self.error_response(
|
||||
data=str(e), message='xatolik'
|
||||
)
|
||||
|
||||
|
||||
class DoctorCreateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = DoctorCreateUpdateSerializer
|
||||
queryset = Doctor.objects.all()
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
@swagger_auto_schema(
|
||||
responses={
|
||||
201: SuccessResponseSerializer(),
|
||||
400: BaseResponseSerializer(),
|
||||
500: BaseResponseSerializer(),
|
||||
}
|
||||
)
|
||||
def post(self, request):
|
||||
try:
|
||||
serializer = self.serializer_class(data=request.data, context={'user': request.user})
|
||||
if serializer.is_valid():
|
||||
obj = serializer.save()
|
||||
return self.success_response(
|
||||
data=DoctorListSerializer(obj).data,
|
||||
message="malumot qoshildi"
|
||||
)
|
||||
return self.failure_response(
|
||||
data=serializer.data,
|
||||
message="malumot qoshilmadi"
|
||||
)
|
||||
except Exception as e:
|
||||
return self.error_response(data=str(e), message='xatolar')
|
||||
|
||||
|
||||
|
||||
class DoctorDeleteUpdateApiView(generics.GenericAPIView, ResponseMixin):
|
||||
serializer_class = DoctorCreateUpdateSerializer
|
||||
queryset = Doctor.objects.all()
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
@swagger_auto_schema(
|
||||
responses={
|
||||
200: SuccessResponseSerializer(),
|
||||
400: BaseResponseSerializer(),
|
||||
500: BaseResponseSerializer(),
|
||||
}
|
||||
)
|
||||
def patch(self, request, id):
|
||||
try:
|
||||
obj = get_object_or_404(Doctor, id=id, user=request.user)
|
||||
serializer = self.serializer_class(data=request.data, instance=obj)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return self.success_response(
|
||||
message='Malumot tahrilandi'
|
||||
)
|
||||
return self.failure_response(
|
||||
data=serializer.errors,
|
||||
message='Malumot tahrirlanmadi'
|
||||
)
|
||||
except Exception as e:
|
||||
return self.error_response(data=str(e), message='xatolik')
|
||||
|
||||
@swagger_auto_schema(
|
||||
responses={
|
||||
204: SuccessResponseSerializer(),
|
||||
400: BaseResponseSerializer(),
|
||||
500: BaseResponseSerializer(),
|
||||
}
|
||||
)
|
||||
def delete(self, request, id):
|
||||
try:
|
||||
obj = get_object_or_404(Doctor, id=id, user=request.user)
|
||||
obj.delete()
|
||||
return self.success_response(message='Malumot ochirildi', status_code=204)
|
||||
except Exception as e:
|
||||
return self.error_response(data=str(e), message='xatolik')
|
||||
Reference in New Issue
Block a user