The challenge of this question is clear from the update 2 which is the current state of it, you can read it full to understand its context if you want
:)
I have the following model that I want to serialize to expose via REST
class RehabilitationSession(models.Model):
patient = models.ForeignKey('userprofiles.PatientProfile', null=True, blank=True,verbose_name='Paciente', related_name='patientprofile')
slug = models.SlugField(max_length=100, blank=True)
medical = models.ForeignKey('userprofiles.MedicalProfile', null=True, blank=True,
verbose_name='Médico tratante')
therapist = models.ForeignKey('userprofiles.TherapistProfile', null=True, blank=True, verbose_name='Terapeuta')
date_session_begin = models.DateTimeField(default=timezone.now(), verbose_name = 'Fecha de inicio')
upper_extremity = MultiSelectField(
max_length=255,
choices=EXTREMITY_CHOICES,
blank=False,
verbose_name='Extremidad Superior'
)
affected_segment = models.ManyToManyField(AffectedSegment,verbose_name='Segmento afectado')
movement = ChainedManyToManyField(
Movement, #Modelo encadenado
chained_field = 'affected_segment',
chained_model_field = 'corporal_segment_associated',
verbose_name='Movimiento'
)
metrics = models.ManyToManyField(Metric, blank=True, verbose_name='Métrica')
date_session_end = models.DateTimeField(default=timezone.now(), verbose_name = 'Fecha de finalización')
period = models.CharField(max_length=25,blank=True, verbose_name='Tiempo de duración de la sesión')
class Meta:
verbose_name = 'Sesiones de Rehabilitación'
def __str__(self):
return "%s" % self.patient
To serialize the fields that are Foreingkey, I am basing myself on this REST Framework documentation .
My serializers.py file is this:
from .models import RehabilitationSession
from rest_framework import serializers
class RehabilitationSessionSerializer(serializers.HyperlinkedModelSerializer):
patient = serializers.HyperlinkedIdentityField(view_name='patientprofile',)
class Meta:
model = RehabilitationSession
fields = ('url','id','patient',
'date_session_begin','status','upper_extremity',
'date_session_end', 'period','games','game_levels',
'iterations','observations',)
I am using HyperlinkedIdentityField because my model is serialized with HyperlinkedModelSerializer, but It is not clear to me how I should serialize it according to the options that are given there. It says that HyperlinkedIdentityField
can also be used on an attribute of the object, and the idea is that in the view of my api when the model is serialized, show me the url of that field, which is an instance of the PatientProfile model, is say a record of a patient.
UPDATE
My main file urls.py
where I include the routes to determine the urls is:
from django.conf.urls import url, include #patterns
from django.contrib import admin
from .views import home, home_files
# REST Framework packages
from rest_framework import routers
from userprofiles.views import UserViewSet, GroupViewSet, PatientProfileViewSet
from medical_encounter_information.views import RehabilitationSessionViewSet
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)
router.register(r'rehabilitation-session', RehabilitationSessionViewSet)
router.register(r'patientprofile', PatientProfileViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^chaining/', include('smart_selects.urls')),
url(r'^$', home, name='home'),
url(r'^', include('userprofiles.urls')),
#Call the userprofiles/urls.py
url(r'^', include('medical_encounter_information.urls' )),
#Call the medical_encounter_information/urls.py
# which is a regular expression that takes the desired urls and passes as an argument
# the filename, i.e. robots.txt or humans.txt.
url(r'^(?P<filename>(robots.txt)|(humans.txt))$',
home_files, name='home-files'),
#REST Frameworks url's
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
When I try to access the url of my api rest of said model, I get the following message in my console:
File "/home/bgarcial/.virtualenvs/neurorehabilitation_projects_dev/lib/python3.4/site-packages/rest_framework/relations.py", line 355, in to_representation
raise ImproperlyConfigured(msg % self.view_name)
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "patientprofile". You may have failed to include the related model in your API, or incorrectly configured the 'lookup_field' attribute on this field.
[08/Mar/2016 16:05:45] "GET /api/rehabilitation-session/ HTTP/1.1" 500 165647
And in my browser this:
How can I serialize a ForeignKey field? I appreciate your help.
UPDATE 2
I wanted to try using the nested relationships as I have suggested in this post, given that it would also be good to have in the serialization of my model in this case rehabilitation session, the fields of the patient of that session, the doctor of that session and the therapist of that session and not their respective urls that take me to the data themselves, for usability purposes and I imagine reading for some third application, although I also imagine that by the url you can also access the values and keys of the json of each url right?
Well, at this moment, I have them like this:
I would like to be able to organize my data in the following way:
{
"url": "http://localhost:8000/api/rehabilitation-session/9/",
"id": 9,
"patient": [
{'id' : 1, 'full_name' : 'Andres Enfermizo',
'diagnostic' : 'Diabetes', 'time_of_evolution' : '3 months'
},
"medical": [
{'id' : 1, 'full_name' : 'Doctor House',
'specialty' : 'Epidemiologist', 'xperience' : '23 years'
} ,
]
"therapist": [
{'id' : 1, 'full_name' : 'Christian',
'specialty' : 'Legs', 'xperience' : '13 years'
} ,
]
"affected_segment": [
{'id' : 1, 'affected_segment' : 'shoulder',
'damage' : '30%', 'time_of_retrieve' : '10 months'
} ,
],
}
So according to the documentation, Nested Relationships or even < Could you help?
Custom relational fieldsI have done this by following the Nested Relationships guide in this way , for now only for the case of showing in a nested way the patient's data in the serialization of the rehabilitation session:
Serializing the model PatientProfile
:
class PatientProfileSerializer(serializers.ModelSerializer):
class Meta:
model = PatientProfile
fields = ('url','id','user','full_name','time_of_evolution','diagnostic','marital_status','educational_level','partner_full_name','partner_relationship','partner_phone','partner_gender',
'care_provider',)
The PatientProfileViewset
view that the serialized model will expose
class PatientProfileViewSet(viewsets.ModelViewSet):
queryset = PatientProfile.objects.all()
serializer_class = PatientProfileSerializer
Now serialize my model RehabilitationSession
:
class RehabilitationSessionSerializer(serializers.ModelSerializer):
patient = PatientProfileSerializer(many=True, read_only=True)
class Meta:
model = RehabilitationSession
fields = ('url','id','patient',
#'affected_segment',
'date_session_begin','status','upper_extremity',
'date_session_end', 'period','games','game_levels',
'iterations','observations',)
The RehabilitationSessionViewSet
view that the serialized model will expose
class RehabilitationSessionViewSet(viewsets.ModelViewSet):
queryset = RehabilitationSession.objects.all()
serializer_class = RehabilitationSessionSerializer
And these are my routers for each serialized model to access them by url in the browser. They are in my main urls.py:
from django.conf.urls import url, include #patterns
from django.contrib import admin
from .views import home, home_files
# REST Framework packages
from rest_framework import routers
from userprofiles.views import (UserViewSet, GroupViewSet, PatientProfileViewSet,)
from medical_encounter_information.views import (RehabilitationSessionViewSet,)
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'groups', GroupViewSet)
router.register(r'rehabilitation-session', RehabilitationSessionViewSet)
router.register(r'patientprofile', PatientProfileViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
...
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
I get this message when I enter the url link
Any guidance will be highly appreciated. :)