Credit: Josh Sorenson

How to Use Foreign Keys in Django Models

OnlyGod Ovbije

--

Hello Everyone, today I will be simply building a simple Records and Schedule App for hospitals to store records of immunized patients, so it’s like a hospital e-registry system.

Sometimes, one has to build an app, that comprises of models that depend on one another, it can sometimes be complicated as a beginner using Django, this tutorial will help to make the process less difficult.

App Structural

Records Schedule App (models would include):

  • Records (all records you have)
  • Schedules (all the schedules for each record)

Templates

  • add templates for records and schedules

To access the app source code visit the github link — source code

STEP 1

Using your command prompt ( I am using Linux)

mkdir ehospital_systempython3 –versionpip install pipenvpipenv shellpip install Djangodjango-admin startproject edit_hospitalcd edit_hospitalpython manage.py startapp hospital

STEP 2

add the app to settings.py

INSTALLED_APPS = [# my _app'hospital',# your app_name#....'django.contrib.admin',

STEP 3

In your models.py add Record models

# .. hospital/models.py
class Record(models.Model):
slug = models.SlugField()
first_name = models.CharField(max_length = 200) last_name = models.CharField(max_length = 200) birth_date = models.DateTimeField() weight = models.CharField(max_length=10) height = models.CharField(max_length=10) parent_name = models.CharField(max_length=200) parent_mobile = models.CharField(max_length=16) home_address = models.CharField(max_length=300)
def __str__(self):
return self.first_name + " " + self.last_name

Also, add also the Schedule model in models.py

# .. hospital/models.py
class Schedule(models.Model):
slug = models.SlugField()
date_immunized = models.DateTimeField() initial_date = models.DateTimeField() record = models.ForeignKey(Record, on_delete = models.SET_NULL, null =True) disease_type = models.CharField(max_length = 30) vaccine_type = models.CharField(max_length=30) position = models.IntegerField()
def __str__(self):
return self.vaccine_type + " for " + self.disease_type

STEP 4:

in your app views add

# .. hospital/views.pyclass RecordListView(ListView):
model = Record
class RecordDetailView(DetailView):
model = Record

STEP 5:

create urls.py in the app: hospital/urls.py

# .. hospital/urls.pyfrom django.urls import pathfrom .views import RecordListView, RecordDetailView, ScheduleDetailViewapp_name = 'hospital'urlpatterns = [path('',RecordListView.as_view(), name='list' ),path('<slug>', RecordDetailView.as_view(), name="detail"),]

urls.py in your Django project

# ... edit_hospital/urls.py 
from django.contrib import adminfrom django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include('hospital.urls', namespace = 'hospital')),]

Run app

python manage.py migrationspython manage.py migratepython manage.py createsuperuserpython manage.py runserver

STEP 6:

Templates

— inside the app make this folder, of app_name and create an HTML template (base.html it should look like this: hospital/base.html

# .. hospital/base.html<!doctype html><html lang="en"><head><!-- Required meta tags --><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><!-- Bootstrap CSS --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"><title>EHospital App</title></head><body class="container">{% block content %}{% endblock content %}<!-- Optional JavaScript --><!-- jQuery first, then Popper.js, then Bootstrap JS --><script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script><script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script></body></html>

…. templates/hospital/records_list.html >> this is the default template name for using the ListView in Django views

# ... hospital/records_list.html
{% extends 'hospital/base.html' %}
{% block content %}<h1> Your Records Page</h1><br><ul class="list-group">{% for object in object_list %}<li class="list-group-item"><a href="{{ object.get_absolute_url }}">{{ object }}</a></li>{% endfor %}</ul>{% endblock %}

…. templates/hospital/records_detail.html >> this is the default template name for using the DetailView in Django views

# .. hospital/records_detail.html{% extends 'hospital/base.html' %}
{% block content %}
<h1> Detail for a Record </h1><p>{{ object.first_name }}</p><p> {{ object.home_address}}</p><h3> Date Immunized (for vaccine)</h3>{% endblock %}

STEP 7:

add records to your Record model

go to URL — http://127.0.0.1:8000/

records in the app

Before we start making use of our Schedule models you have to make some additions

For the detail go to http://127.0.0.1:8000/third

third: here is the slug, I added to it from the admin site while creating the record

the detail page for a record

STEP 8:

Now to link the schedule model to the model of the record, we add this under the Record model in models.py

the property helps to get all the schedules in the schedule model to the Record model

@propertydef schedules(self):return self.schedule_set.all().order_by('position')

STEP 9:

Now in your views.py add DetailView for the Schedule model.

this simply assigns Slug ( a short label for something) to the models

# ...class ScheduleDetailView(View):def get(self, request, record_slug, schedule_slug, *args, **kwargs):record_qs = Record.objects.filter(slug=record_slug)if record_qs.exists():record = record_qs.first()schedule_qs = record.schedules.filter(slug=schedule_slug)if schedule_qs.exists():schedule = schedule_qs.first()context = {'object' : schedule}return render(request, "hospital/schedule_detail.html", context)

STEP 10:

In your models.py again update the Schedule model

#.....def get_absolute_url(self):return reverse("hospital:record-detail", kwargs={'record_slug': self.record.slug,'schedule_slug':self.slug,})

STEP 11:

Then in your urls.py in your Django app update it, and add the ScheduleDetailView

#....hospital/urls.py
#...
path('<record_slug>/<schedule_slug>/', ScheduleDetailView.as_view(), name="record-detail"),]

STEP 12:

Now create a template for the ScheduleDetailView,

templates/hospital/schedule_detail.html >> this is the default for Detailview in Django

{% extends 'hospital/base.html' %} {% block content %}<h3> Schedules For a Record</h3><h6> {{ object }}</h6>{% endblock%}

Lastly, we don’t need a ListView, for the Schedule model, cause it will be added in the same place as the Record detail page. So update your record detail template as

#.... hospital/record_detail.html
{% extends 'hospital/base.html' %}
{% block content %}<h1> Detail for {{ object.first_name }} Record </h1><h5> Birth Date : {{object.birth_date}} </h5><h5> Weight : {{object.weight }}</h5><h5>Height : {{ object.height }}</h5><h5> Parents : {{ object.parent_name }} </h5><h5> Parent Mobile Number : {{ object.parent_mobile}}</h5><h5>Home Address : {{object.home_address}}</h5><br><table class="table table-striped"><thead><tr><th scope="col">#</th><th scope="col">Date Immunized</th><th scope="col">Vaccine Type</th><th scope="col">Disease Type</th></tr></thead><tbody>{% for schedule in object.schedules %}<tr><th scope="row">{{schedule.position}}</th><td> <a href="{{ schedule.get_absolute_url }}">{{ schedule.date_immunized }}</a></td><td> {{ schedule.vaccine_type }}</td><td> {{ schedule.disease_type }}</td></tr>
{% endfor%}</tbody></table>{% endblock %}

STEP 13:

Next, add Schedules for records in from your admin page

adding schedules to a record
showing list of schedules for a single record

Well Done.😉

Now You can add UpdateView to edit both models and do much other stuff…

I hope this was helpful

Having any errors or need to understand it, more follow this video guide from JustDjango, I got most if not all from it.

https://www.youtube.com/watch?v=zu2PBUHMEew

Thanks for reading this article! Leave a comment below if you have any questions or suggestions.

You can follow me here on Medium

You can also find me on 👉 Instagram / LinkedIn / Github🔥

To Support Me 💗

--

--