Reputation: 199
I am trying to use django to organize and manage my clinical research data. I think I can get by with just the admin interface, since this is a behind-the-scenes database that does not need to go public. I can program, but never in python before, so I am getting stuck on simple things.
I have Patients who make multiple Visits. Each Visit involves multiple Scans. In the admin interface, I can see all the Visits and all the Scans, as inlines on each Patient's page. However, when adding a new Scan, how can I make it so that the choice of which Visit to associate it with is limited to Visits for the Patient in question, not other Patients?
Models (simplified):
class Patient(models.Model):
patient_id = models.CharField(max_length=16, primary_key=True)
first_name = models.CharField(max_length=64)
last_name = models.CharField(max_length=64)
class Visit(models.Model):
patient = models.ForeignKey(Patient)
visit_date = models.DateTimeField()
class Scan(models.Model):
patient = models.ForeignKey(Patient)
visit = models.ForeignKey(Visit)
scan_type = models.CharField(max_length=32)
Thanks a lot for any help...
Upvotes: 2
Views: 1498
Reputation: 704
Two examples only slightly different:
First:
class ScanInlineAdmin(admin.TabularAdmin):
model = Scan
formset = ScanInlineFormset
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "visit":
patient = self.get_object(kwargs['request'], Patient)
kwargs["queryset"] = Visit.objects.filter(patient=patient)
return super(ScanInlineAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
def get_object(self, request, model):
object_id = request.META['PATH_INFO'].strip('/').split('/')[-1]
try:
object_id = int(object_id)
except ValueError:
return None
return model.objects.get(pk=object_id)
Second:
class ScanInline(admin.TabularInline):
model = Scan
formset = ScanInlineFormset
def formfield_for_dbfield(self, field, **kwargs):
if field.name == 'visit':
# Note - get_object hasn't been defined yet
patient = self.get_object(kwargs['request'], Patient)
vists = Visit.objects.filter(patient=patient)
return forms.ModelChoiceField(queryset=visits)
return super(ScanInline, self).formfield_for_dbfield(field, **kwargs)
def get_object(self, request, model):
object_id = request.META['PATH_INFO'].strip('/').split('/')[-1]
try:
object_id = int(object_id)
except ValueError:
return None
return model.objects.get(pk=object_id)
You may find this article helpful. I assume your in the patient page admin edit/view where you want to enter the new scan. Is that correct?
Upvotes: 1