Skip to content

Commit

Permalink
Add models and appointment views (#6)
Browse files Browse the repository at this point in the history
* Add custom models for Doctor, Patient, and Appointment

* Add URL routing for create_appointment view

* Add URL pattern for list_appointments view

* Add update and delete appointment view functions

* Add URL patterns for update and delete appointment views

* Update docker-compose with correct environment variables

* Update logging configuration

* Fix request data keys in create_appointment and update docker-compose

* Update appointment views

---------

Co-authored-by: staging-devin-ai-integration[bot] <166158716+staging-devin-ai-integration[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 7eaf2f4 commit aa26436
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 13 deletions.
Empty file added appointments/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions appointments/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions appointments/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class AppointmentsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'appointments'
47 changes: 47 additions & 0 deletions appointments/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 5.0.6 on 2024-07-01 18:17

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
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')),
('specialization', models.CharField(max_length=100)),
('phone_number', models.CharField(max_length=15)),
('address', models.TextField()),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Patient',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('phone_number', models.CharField(max_length=15)),
('address', models.TextField()),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Appointment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('appointment_date', models.DateTimeField()),
('symptoms', models.TextField()),
('prescription', models.TextField(blank=True, null=True)),
('doctor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='appointments.doctor')),
('patient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='appointments.patient')),
],
),
]
Empty file.
29 changes: 29 additions & 0 deletions appointments/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from django.db import models
from django.contrib.auth.models import User

class Doctor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
specialization = models.CharField(max_length=100)
phone_number = models.CharField(max_length=15)
address = models.TextField()

def __str__(self):
return self.user.username

class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=15)
address = models.TextField()

def __str__(self):
return self.user.username

class Appointment(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
appointment_date = models.DateTimeField()
symptoms = models.TextField()
prescription = models.TextField(blank=True, null=True)

def __str__(self):
return f"Appointment with Dr. {self.doctor.user.username} on {self.appointment_date}"
3 changes: 3 additions & 0 deletions appointments/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
9 changes: 9 additions & 0 deletions appointments/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path
from .views import create_appointment, list_appointments, update_appointment, delete_appointment

urlpatterns = [
path('create/', create_appointment, name='create_appointment'),
path('list/', list_appointments, name='list_appointments'),
path('update/<int:appointment_id>/', update_appointment, name='update_appointment'),
path('delete/<int:appointment_id>/', delete_appointment, name='delete_appointment'),
]
94 changes: 94 additions & 0 deletions appointments/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from django.shortcuts import render
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.dateparse import parse_datetime
from .models import Doctor, Patient, Appointment
import json
import logging

logger = logging.getLogger(__name__)

@csrf_exempt
def create_appointment(request):
logger.info(f"Received request at {request.path}")
if request.method == 'POST':
try:
data = json.loads(request.body)
logger.info(f"Request data: {data}")
doctor_id = data.get('doctor')
patient_id = data.get('patient')
appointment_date = parse_datetime(data.get('scheduled_time'))
symptoms = data.get('symptoms')

doctor = Doctor.objects.get(id=doctor_id)
patient = Patient.objects.get(id=patient_id)
appointment = Appointment.objects.create(
doctor=doctor,
patient=patient,
appointment_date=appointment_date,
symptoms=symptoms
)
logger.info(f"Appointment created with ID: {appointment.id}")
return JsonResponse({'status': 'success', 'appointment_id': appointment.id})
except Doctor.DoesNotExist:
logger.error("Doctor not found")
return JsonResponse({'status': 'error', 'message': 'Doctor not found'}, status=404)
except Patient.DoesNotExist:
logger.error("Patient not found")
return JsonResponse({'status': 'error', 'message': 'Patient not found'}, status=404)
except Exception as e:
logger.error(f"Exception: {str(e)}")
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)

@csrf_exempt
def list_appointments(request):
if request.method == 'GET':
appointments = Appointment.objects.all()
appointments_list = [
{
'id': appointment.id,
'doctor': appointment.doctor.user.username,
'patient': appointment.patient.user.username,
'appointment_date': appointment.appointment_date,
'symptoms': appointment.symptoms,
'prescription': appointment.prescription
}
for appointment in appointments
]
return JsonResponse({'status': 'success', 'appointments': appointments_list})

@csrf_exempt
def update_appointment(request, appointment_id):
if request.method == 'PUT':
try:
data = json.loads(request.body)
appointment_date_str = data.get('appointment_date')
appointment_date = parse_datetime(appointment_date_str) if appointment_date_str else None
symptoms = data.get('symptoms')
prescription = data.get('prescription')

appointment = Appointment.objects.get(id=appointment_id)
if appointment_date:
appointment.appointment_date = appointment_date
if symptoms:
appointment.symptoms = symptoms
if prescription:
appointment.prescription = prescription
appointment.save()
return JsonResponse({'status': 'success', 'message': 'Appointment updated successfully'})
except Appointment.DoesNotExist:
return JsonResponse({'status': 'error', 'message': 'Appointment not found'}, status=404)
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)

@csrf_exempt
def delete_appointment(request, appointment_id):
if request.method == 'DELETE':
try:
appointment = Appointment.objects.get(id=appointment_id)
appointment.delete()
return JsonResponse({'status': 'success', 'message': 'Appointment deleted successfully'})
except Appointment.DoesNotExist:
return JsonResponse({'status': 'error', 'message': 'Appointment not found'}, status=404)
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
12 changes: 6 additions & 6 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ services:
args:
PYTHON_BUILD_VERSION: "3.11"
environment: &app-environment
DEBUG: "False"
DEBUG: "True"
RUN_MIGRATIONS: "True"
DJANGO_SECRET_KEY: "insecure-key-fill-with-your-own"
DJANGO_SECRET_KEY: "l$$0cd-!v9qc382qvufq-omh_lq0upson)u+02f64fj1=m)@o4b"
# Postgres params
POSTGRES_HOST: "db"
POSTGRES_PORT: "5432"
POSTGRES_DB: "postgres"
POSTGRES_HOST: "roundhouse.proxy.rlwy.net"
POSTGRES_PORT: "31991"
POSTGRES_DB: "railway"
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
POSTGRES_PASSWORD: "biFnCiGBxBduyHxKGNMXkCxBOdkPJmGh"
# Redis params
REDISHOST: "redis"
REDISPORT: "6379"
Expand Down
36 changes: 30 additions & 6 deletions railway_django_stack/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
"django.contrib.staticfiles",
"django_celery_beat",
"django_celery_results",
# Your custom apps would come here
"railway_django_stack", # Add the custom app here
"appointments", # Add the new appointments app here
]

MIDDLEWARE = [
Expand Down Expand Up @@ -78,11 +79,11 @@
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"HOST": config("PGHOST", default="db"),
"USER": config("PGUSER", default="postgres"),
"NAME": config("PGDATABASE", default="postgres"),
"PASSWORD": config("PGPASSWORD", default="postgres"),
"PORT": config("PGPORT", default=5432),
"HOST": "roundhouse.proxy.rlwy.net",
"USER": "postgres",
"NAME": "railway",
"PASSWORD": "biFnCiGBxBduyHxKGNMXkCxBOdkPJmGh",
"PORT": 31991,
"CONN_MAX_AGE": 60,
}
}
Expand Down Expand Up @@ -147,3 +148,26 @@
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# Logging configuration
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {
"level": "DEBUG",
"class": "logging.StreamHandler",
},
},
"root": {
"handlers": ["console"],
"level": "DEBUG",
},
"loggers": {
"django": {
"handlers": ["console"],
"level": "DEBUG",
"propagate": True,
},
},
}
3 changes: 2 additions & 1 deletion railway_django_stack/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.urls import path, include

import railway_django_stack.example_views as example_views

Expand All @@ -24,4 +24,5 @@
path("healthcheck/", example_views.health_check, name="health_check"),
path("test-task/", example_views.test_task, name="test_task"),
path("admin/", admin.site.urls),
path("appointments/", include("appointments.urls")),
]

0 comments on commit aa26436

Please sign in to comment.