Reputation: 8054
I'm figuring out how serializers can be merged or nested into each other. In this example I have a column model (consisting of Column
class) and data that belong to the column model (consisting of Data class
). My problems is that I don't know how to call ModelSerializer from another serializer class and pass the arguments (the result is always empty).
Can you advice me if my model is correct for this situation and how to create the desired JSON so that the result reuses existing serializers and avoids duplicating any data?
Note: in best case the data attributes should be dependent on each other, so that only those data get serialized that are defined as columns.
models.py
class Column(models.Model):
data = models.CharField(max_length=200)
title = models.CharField(max_length=200)
def __str__(self):
return self.order
class Data(models.Model):
doc = models.CharField(max_length=200)
order = models.CharField(max_length=200)
nothing = models.CharField(max_length=200)
def __str__(self):
return self.order
Desired output:
{
"columns": [
{
"data": "doc",
"title": "Doc."
},
{
"data": "order",
"title": "Order no."
},
{
"data": "nothing",
"title": "Nothing"
}
],
"data": [
{
"doc": "564251422",
"nothing": 0.0,
"order": "56421"
},
{
"doc": "546546545",
"nothing": 0.0,
"order": "98745"
}
]
}
But the result with ModelSerializer is like this:
[
{
"doc": "564251422",
"order": "56421",
"nothing": "0.0"
},
{
"doc": "546546545",
"order": "98745",
"nothing": "0.0"
}
]
Upvotes: 2
Views: 1050
Reputation: 10238
You have to add a model that contains columns
and data
attributes because they are currently not linked.
your models.py
file :
class Table(models.Model):
pass
class Column(models.Model):
data = models.CharField(max_length=200)
title = models.CharField(max_length=200)
table = models.ForeignKey(Table)
def __str__(self):
return self.order
class Line(models.Model):
doc = models.CharField(max_length=200)
order = models.CharField(max_length=200)
nothing = models.CharField(max_length=200)
table = models.ForeignKey(Table)
def __str__(self):
return self.order
your serializer.py
file :
# import your related models and serializers
class ColumnSerializer(serializers.ModelSerializer):
class Meta:
model = Column
fields = [
'data',
'title'
]
class LineSerializer(serializers.ModelSerializer):
class Meta:
model = Line
fields = [
'doc',
'order',
'nothing'
]
class TableSerializer(serializers.ModelSerializer):
columns = ColumnSerializer(many=True)
lines = LineSerializer(many=True)
class Meta:
model = Table
fields = [
'columns',
'lines'
]
Now use the TableSerializer
serializer to serialize and deserialize your Table
object.
Concerning your models, Line
instead of Data
is maybe more appropriate. And
Read Django-Rest-Framework - NestedRelationships for more information and learn how to support write-operations to a nested serializer field.
Upvotes: 3
Reputation: 5475
First you need to modify you models. You can make data
ForeignKey
field in Column
model like:
class Column(models.Model):
data = models.ForeignKey("Data")
title = models.CharField(max_length=200)
Next create a new serializer for Data
like:
class DataSerializer(serializers.ModelSerializer):
class Meta:
model = Data
Now you can use DataSerializer
in your ColumnSerializer
to get data for each column like:
class ColumnSerializer(serializers.ModelSerializer):
data = DataSerializer(read_only=True)
class Meta:
model = Column
This would give output like:
[
{
"title" : "Doc",
"data" :{
"doc": "564251422",
"nothing": 0.0,
"order": "56421"
}
},
{
"title" : "Order no.",
"data" :{
"doc": "546546545",
"nothing": 0.0,
"order": "98745"
}
}
]
Upvotes: 0