jor*_*lle 8 django django-models django-rest-framework
我正在处理Django Rest Framework项目,我的视图的泛型响应不是应用程序客户端所期望的.
应用程序客户端期望相关模型的字段显示为它们在数据库中.给出的示例:model City具有Country模型的外键,由country_id列表示.
是否有任何选项可以将序列化程序默认字段"映射"为自定义字段?我查看了Django Rest Framework文档,但我只找到了"serializer_field_mapping",但我不知道它是否符合我的要求,也不知道如何使用它.
不知怎的,我得到了一个接近的方法,但只是在获取数据的情况下 - 创建/更新抛出一些我没有得到如何管理的错误.:(
Bellow我附上了models.py文件,加上实际输出和所需的输出.此外,如果可能,我想检索与国家/地区相关的数据(如果存在)与数据库列field_id名称相结合.
提前致谢,
models.py
from django.db import models
from django.contrib.postgres.fields import ArrayField
class Country(models.Model):
name = models.CharField(max_length=150, unique=True, blank=False)
class Meta:
db_table = 'countries'
class Region(models.Model):
name = models.CharField(max_length=150, unique=True, blank=False)
code = models.CharField(max_length=150, blank=True)
class Meta:
db_table = 'regions'
class City(models.Model):
country = models.ForeignKey(Country)
region = models.ForeignKey(Region, null=True, blank=True, default=None)
name = models.CharField(max_length=150, unique=True, blank=False)
postal_codes = ArrayField(models.CharField(max_length=12, blank=True), null=True, blank=True, default=None)
def __str__(self):
if not self.region:
return '%s (%s)' % (self.name, self.country.name)
return '%s, %s (%s)' % (self.name, self.region.name, self.country.name)
class Meta:
db_table = 'cities'
Run Code Online (Sandbox Code Playgroud)
实际产量:
[
{
"id": 1,
"name": "San Francisco",
"postal_codes": null,
"country": 1,
"region": 1
},
{
"id": 2,
"name": "Palo Alto",
"postal_codes": null,
"country": 1,
"region": 1
},
{
"id": 3,
"name": "New York City",
"postal_codes": null,
"country": 1,
"region": 2
},
{
"id": 4,
"name": "London",
"postal_codes": null,
"country": 2,
"region": null
}
]
Run Code Online (Sandbox Code Playgroud)
期望的输出:
[
{
"id": 1,
"country_id": 1,
"region_id": 1,
"name": "San Francisco",
"postal_codes": null
},
{
"id": 2,
"country_id": 1,
"region_id": 1,
"name": "Palo Alto",
"postal_codes": null
},
{
"id": 3,
"country_id": 1,
"region_id": 2,
"name": "New York City",
"postal_codes": null
},
{
"id": 4,
"country_id": 2,
"region_id": null,
"name": "London",
"postal_codes": null
}
]
Run Code Online (Sandbox Code Playgroud)
您可以使用source序列化程序中字段的参数来实现此目的.例如:
from rest_framework import serializers
from .models import City
class CitySerializer(serializers.ModelSerializer):
country_id = serializers.IntegerField(source='country')
region_id = serializers.IntegerField(source='region')
class Meta:
model = City
fields = ('id', 'country_id', 'region_id', 'name', 'postal_codes')
Run Code Online (Sandbox Code Playgroud)
编辑:正如雅罗斯拉夫所指出的那样,当你这样做时,你不需要包括source.但请注意,仅包含country_id或列region_id在fields列表中是不够的.您仍然需要在序列化程序中指定字段,例如country_id = serializers.IntegerField()并将其包括在fields.
谢谢大家。最后我明白了。参见下面的代码。由于没有选择在答案注释上添加大量行,因此我回答了我的问题。
serializers.py
from rest_framework import serializers
from .models import Country, Region, City
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
fields = ('id', 'name')
class RegionSerializer(serializers.ModelSerializer):
class Meta:
model = Region
fields = ('id', 'name', 'code')
class CitySerializer(serializers.ModelSerializer):
country_id = serializers.PrimaryKeyRelatedField(
queryset=Country.objects.all(),
required=True,
source='country',
)
region_id = serializers.PrimaryKeyRelatedField(
queryset=Region.objects.all(),
allow_null=True,
required=False,
source='region',
)
country = CountrySerializer(
read_only=False,
required=False,
)
region = RegionSerializer(
required=False,
allow_null=True,
read_only=True,
)
class Meta:
model = City
fields = (
'id',
'country', 'region',
'name', 'postal_codes',
'country_id', 'region_id',
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5973 次 |
| 最近记录: |