问题
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"
}
]
回答1:
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.
回答2:
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"
}
}
]
来源:https://stackoverflow.com/questions/33957167/django-nesting-serializers-in-each-other