当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值
Posted
技术标签:
【中文标题】当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值【英文标题】:how to set foreignkey value in child serializer in django rest framework when the parent record exists 【发布时间】:2019-02-28 09:53:13 【问题描述】:我有两个模型首先作为父模型“Country”,在第二个模型之前填充为子模型“City”。如下
class Country(models.Model):
name = models.CharField(max_length=35)
icon = models.ImageField()
def __str__(self):
return self.name
class City(models.Model):
name = models.CharField(max_length=35)
country = models.ForeignKey(to=Country, on_delete=models.CASCADE)
def __str__(self):
return self.name
我的 serializers.py 满足我的需要如下:
class CountrySerializer(ModelSerializer):
class Meta:
model = Country
fields = '__all__'
class CitySerializer(ModelSerializer):
country = serializers.PrimaryKeyRelatedField(queryset=Country.objects.all())
class Meta:
model = City
fields = ('name', 'country')
view.py
class CountryAPIView(ListAPIView):
queryset = Country.objects.all()
serializer_class = CountrySerializer
permission_classes = [AllowAny, AllowAnonymous]
class CityAPIView(ListAPIView):
queryset = City.objects.all()
serializer_class = CitySerializer
permission_classes = [AllowAny, AllowAnonymous]
def post(self, request):
serializer = CitySerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
serializer.create(validated_data=request.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.error_messages,
status=status.HTTP_400_BAD_REQUEST)
现在,当我运行 get api 时,它会运行并给我一个很好的结果。但是当我试图创建一个新城市并在 json 中设置“国家”:“id”时,我得到了这个错误
无法分配“2”:“City.country”必须是“Country”实例。
所以如果我不清楚,我需要的是在创建城市时为城市设置外键,而不是创建城市和国家,
请任何人提供解决方案帮助,因为我尝试了很多方法并阅读了关于这一点的 django rest 框架文档,但我没有得到它。
【问题讨论】:
【参考方案1】:首先,raise_exception
应该是一个布尔值(True
或 False
)
您可以通过使用从ListCreateAPIView 继承视图类来避免此错误
from rest_framework.generics import ListCreateAPIView
class CityAPIView(ListCreateAPIView):
queryset = City.objects.all()
serializer_class = CitySerializer
permission_classes = [AllowAny, AllowAnonymous]
如果您正在使用ListCreateAPIView
,您不想使用 post()
方法,因为 DRF 会很好地处理该部分。
建议 由于您正在处理模型的 CRUD 功能,因此您可以使用 DRF 的 ModelViewset 类
【讨论】:
你能看到这个问题吗,***.com/questions/52850354/…非常感谢@JPG【参考方案2】:您没有使用经过验证的数据来创建新城市,只需更改此行:
serializer.create(validated_data=request.data)
到这里:
serializer.save()
当您执行serializer.save()
时,序列化程序将使用其经过验证的数据。
此外,DRF 有一个通用视图 (ListCreateAPIView),涵盖了您的用例。
【讨论】:
以上是关于当父记录存在时,如何在 django rest 框架的子序列化程序中设置外键值的主要内容,如果未能解决你的问题,请参考以下文章
Django REST框架:POST请求:仅在数据不存在时如何保存数据
如何使用 Django Rest Framework 在 Django 中进行操作日志记录
django-rest-framework 和 swagger api 文档