Reputation: 25
I am trying to get value of foreign key , but i am only getting id, my code below
Model:
class DocumentType(models.Model):
"""Model for type of documents type system is indexing"""
title = models.CharField(max_length=255, null=False)
def __str__(self):
return "{}".format(self.title)
class DocumentsCount(models.Model):
"""Model for type of documents count system is indexing"""
document_type = models.ForeignKey(DocumentType, on_delete=models.CASCADE, related_name='doc_title')
count = models.IntegerField(default=0)
def __str__(self):
return "{}".format(self.document_type)
Serializer
class DocumentCountsSerializer(serializers.ModelSerializer):
title = serializers.ReadOnlyField(source="DocumentType.title")
class Meta:
model = DocumentsCount
fields = "__all__"
Out put I am getting from API
{
"id": 5,
"count": 2,
"document_type": 3
}
document_type should be title , but i am getting ID
this is query
queryset = DocumentsCount.objects.select_related('document_type')
I am not sure what did I did wrong, I am in fact getting ID and Title when u print queryset
and run in sqlite
Upvotes: 1
Views: 7788
Reputation: 11
The easiest way is to use StringRelatedField property/attribute of rest framework while making serializers. It gives output as per the definition in __str__(self) of the model.
See an example (if one to Many: you can use many=True):
Your snippet will go like this:
class DocumentCountsSerializer(serializers.ModelSerializer):
document_type = serializers.StringRelatedField()
class Meta:
model = DocumentsCount
fields = "__all__"
To add on (an additional info), if the serializer was of your class DocumentType
, then we have to use: many=True, example is in subsequent field:
class DocumentTypeSerializer(serializers.ModelSerializer):
# here we use related_name 'doc_title' for the relationship
doc_title = serializers.StringRelatedField(many=True)
class Meta:
model = DocumentsType
fields = "__all__"
Upvotes: 1
Reputation: 12990
You have a mistake in specifying the source. Change it to source="document_type.title"
because you want to say "use the title
of the document_type
field of this instance":
class DocumentCountsSerializer(serializers.ModelSerializer):
title = serializers.CharField(source="document_type.title", read_only=True)
class Meta:
model = DocumentsCount
fields = "__all__"
You were having a problem because there's no field DocumentType
defined on the DocumentsCount
model (the field is document_type
which is a foreign key to DocumentType
).
Upvotes: 4
Reputation: 161
The answer posted by a_k_v is correct and will return a nested serializer within the DocumentCountsSerializer()
.
Alternatively if you want a response like this with:
{
"id": 5,
"count": 2,
"title": "title here"
}
You need to update your serializer accordingly. Considering the query your run with select_related, your serializers will look something like this:
class DocumentCountsSerializer(serializers.ModelSerializer):
title = serializers.SerializerMethodField()
class Meta:
model = DocumentsCount
fields = "__all__"
def get_title(self, obj):
return obj.document_type.title
Upvotes: 0
Reputation: 1608
Update your model to support nested serializer like this
class DocumentTypeSerializer(serializers.ModelSerializer):
class Meta:
model = DocumentType
fields = "__all__"
class DocumentCountsSerializer(serializers.ModelSerializer):
doc_title = DocumentTypeSerializer(many=True)
class Meta:
model = DocumentsCount
fields = "__all__"
By calling the DocumentCountsSerializer for fetching data automatically fetch related foreign key values.
Call the serializer as follows:
queryset = DocumentsCount.objects.all()
serializer = serializers.DocumentTypeSerializer(queryset, many=True)
Upvotes: 0